Checkin und Checkout

Durch die Checkout-Funktion werden unerwartete Ergebnisse vermieden, die auftreten, wenn zwei Benutzer denselben Datensatz gleichzeitig editieren. Das Auschecken sperrt ein Item, wenn ein Anwender es zur Bearbeitung öffnet. Beim Speichern und Schließen wird es dann wieder freigegeben. Eine sinnvolle Funktion, die wir in diesem Teil der Artikelserie unsere Beispielerweiterung integrieren.

Manchmal kommt es vor, dass ein Element als ausgecheckt markiert ist, obwohl es niemand zeitgleich zur Bearbeitung geöffnet hat. Dies passiert in der Regel, wenn ein vorheriges Öffnen nicht korrekt beendet wurde. Beispielsweise wurde der Webbrowser geschlossen, obwohl der Beitrag zur Bearbeitung offen war.

Für Ungeduldige

Sieh dir den geänderten Programmcode in der Diff-Ansicht an und übernimm diese Änderungen in deine Entwicklungsversion.

// https://github.com/astridx/boilerplate/compare/t20...t21.diff

diff --git a/src/administrator/components/com_foos/forms/foo.xml b/src/administrator/components/com_foos/forms/foo.xml
index f451d9e2..1b8a4c73 100644
-- a/src/administrator/components/com_foos/forms/foo.xml
++ b/src/administrator/components/com_foos/forms/foo.xml
@@ -91,6 +91,18 @@
 			size="1"
 		/>

		<field
			name="checked_out"
			type="hidden"
			filter="unset"
		/>

		<field
			name="checked_out_time"
			type="hidden"
			filter="unset"
		/>

 		<field
 			name="ordering"
 			type="ordering"
diff --git a/src/administrator/components/com_foos/sql/install.mysql.utf8.sql b/src/administrator/components/com_foos/sql/install.mysql.utf8.sql
index ab768e01..862fa7c9 100644
-- a/src/administrator/components/com_foos/sql/install.mysql.utf8.sql
++ b/src/administrator/components/com_foos/sql/install.mysql.utf8.sql
@@ -35,3 +35,10 @@ ALTER TABLE `#__foos_details` ADD KEY `idx_language` (`language`);
 ALTER TABLE `#__foos_details` ADD COLUMN  `ordering` int(11) NOT NULL DEFAULT 0 AFTER `alias`;

 ALTER TABLE `#__foos_details` ADD COLUMN  `params` text NOT NULL AFTER `alias`;

ALTER TABLE `#__foos_details` ADD COLUMN `checked_out` int(10) unsigned NOT NULL DEFAULT 0 AFTER `alias`;

ALTER TABLE `#__foos_details` ADD COLUMN `checked_out_time` datetime AFTER `alias`;

ALTER TABLE `#__foos_details` ADD KEY `idx_checkout` (`checked_out`);

diff --git a/src/administrator/components/com_foos/sql/updates/mysql/21.0.0.sql b/src/administrator/components/com_foos/sql/updates/mysql/21.0.0.sql
new file mode 100644
index 00000000..9498eedf
-- /dev/null
++ b/src/administrator/components/com_foos/sql/updates/mysql/21.0.0.sql
@@ -0,0 +1,5 @@
ALTER TABLE `#__foos_details` ADD COLUMN `checked_out` int(10) unsigned NOT NULL DEFAULT 0 AFTER `alias`;

ALTER TABLE `#__foos_details` ADD COLUMN `checked_out_time` datetime AFTER `alias`;

ALTER TABLE `#__foos_details` ADD KEY `idx_checkout` (`checked_out`);
diff --git a/src/administrator/components/com_foos/src/Model/FoosModel.php b/src/administrator/components/com_foos/src/Model/FoosModel.php
index d2cab389..1e8d6c88 100644
-- a/src/administrator/components/com_foos/src/Model/FoosModel.php
++ b/src/administrator/components/com_foos/src/Model/FoosModel.php
@@ -75,10 +75,20 @@ protected function getListQuery()
 		// Select the required fields from the table.
 		$query->select(
 			$db->quoteName(
				array(
					'a.id', 'a.name', 'a.alias', 'a.access',
					'a.catid', 'a.published', 'a.publish_up', 'a.publish_down',
					'a.language', 'a.ordering', 'a.state'
				explode(
					', ',
					$this->getState(
						'list.select',
						'a.id, a.name, a.catid' .
						', a.access' .
						', a.checked_out' .
						', a.checked_out_time' .
						', a.language' .
						', a.ordering' .
						', a.state' .
						', a.published' .
						', a.publish_up, a.publish_down'
					)
 				)
 			)
 		);
@@ -124,6 +134,13 @@ protected function getListQuery()
 			$query->select('(' . $subQuery . ') AS ' . $db->quoteName('association'));
 		}

		// Join over the users for the checked out user.
		$query->select($db->quoteName('uc.name', 'editor'))
			->join(
				'LEFT',
				$db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')
			);

 		// Filter on the language.
 		if ($language = $this->getState('filter.language'))
 		{
diff --git a/src/administrator/components/com_foos/tmpl/foos/default.php b/src/administrator/components/com_foos/tmpl/foos/default.php
index c18a6c04..74f0ef88 100644
-- a/src/administrator/components/com_foos/tmpl/foos/default.php
++ b/src/administrator/components/com_foos/tmpl/foos/default.php
@@ -108,6 +108,9 @@
 									<?php echo HTMLHelper::_('grid.id', $i, $item->id); ?>
 								</td>
 								<th scope="row" class="has-context">
									<?php if ($item->checked_out) : ?>
										<?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'foos.', true); ?>
									<?php endif; ?>
 									<div>
 										<?php echo $this->escape($item->name); ?>
 									</div>

Schritt für Schritt

Neue Dateien

src/administrator/components/com_foos/sql/updates/mysql/21.0.0.sql

Wie alle Eigenschaften eines Foo-Elementes, wird der Zustand in der Datenbank gespeichert. Wir legen zwei Spalten an. Nachfolgend siehst du das Skript, welches bei einer Aktualisierung aufgerufen wird.

src/administrator/components/com_foos/sql/install.mysql.utf8.sql

...
ALTER TABLE `#__foos_details` ADD COLUMN `checked_out` int(10) unsigned NOT NULL DEFAULT 0 AFTER `alias`;
ALTER TABLE `#__foos_details` ADD COLUMN `checked_out_time` datetime AFTER `alias`;
ALTER TABLE `#__foos_details` ADD KEY `idx_checkout` (`checked_out`);

Geänderte Dateien

src/administrator/components/com_foos/forms/foo.xml

Im Formular fügen wir die Felder für das Speichern des Zustands hinzu. Wir verstecken sie mit dem Attribut hidden, da sie hier nicht vom Benutzer geändert werden. Joomla setzt die Werte automatisch im Hintergrund.

src/administrator/components/com_foos/forms/foo.xml

...
<field
  name="checked_out"
  type="hidden"
  filter="unset"
/>

<field
  name="checked_out_time"
  type="hidden"
  filter="unset"
/>
...

src/administrator/components/com_foos/sql/install.mysql.utf8.sql

Die Datenbankänderungen, die wir oben für die Aktualisierung in der separaten Datei eingetragen haben, ergänzen wir im Skript, welches bei einer neuen Installation aufgerufen wird.

src/administrator/components/com_foos/sql/install.mysql.utf8.sql

ALTER TABLE `#__foos_details` ADD COLUMN `checked_out` int(10) unsigned NOT NULL DEFAULT 0 AFTER `alias`;
ALTER TABLE `#__foos_details` ADD COLUMN `checked_out_time` datetime AFTER `alias`;
ALTER TABLE `#__foos_details` ADD KEY `idx_checkout` (`checked_out`);

src/administrator/components/com_foos/src/Model/FoosModel.php

Im Model passen wir alles so an, dass die beiden neuen Spalten korrekt geladen werden.

src/administrator/components/com_foos/src/Model/FoosModel.php

...
protected function getListQuery()
{
...
...
  $query->select(
    $db->quoteName(
      explode(
        ', ',
        $this->getState(
          'list.select',
          'a.id, a.name, a.catid' .
          ', a.access' .
          ', a.checked_out' .
          ', a.checked_out_time' .
          ', a.language' .
          ', a.ordering' .
          ', a.state' .
          ', a.published' .
          ', a.publish_up, a.publish_down'
        )
      )
    )
  );
...
...
  $query->select($db->quoteName('uc.name', 'editor'))
    ->join(
      'LEFT',
      $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')
    );
...

Beachte die Änderung array(...) in explode(', ',$this->getState(...)...).

src/administrator/components/com_foos/tmpl/foos/default.php

src/administrator/components/com_foos/tmpl/foos/default.php

In die Listenansicht fügen wir keine separate Zeile ein. Beim Namen wird ein Symbol angezeigt, wenn das Element gesperrt ist. Für die Anzeige von diesem wähle ich die Funktion, die Joomla in eigenen Erweiterungen einsetzt: echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'foos.', true). Die übernimmt gleichzeitig die Prüfung, ob der Beitrag freigegeben ist oder nicht.

...
<?php if ($item->checked_out) : ?>
  <?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'foos.', true); ?>
<?php endif; ?>
...

Ich habe es hier unkompliziert gehalten. Ich prüfe nicht, ob jemand berechtigt ist, einen ausgecheckten Beitrag wieder freizugeben. Die Komponenten in Joomla gestalten dies restriktiver. In comcontact sieht die betreffende Zeile beispielsweise so aus: `<?php echo HTMLHelper::('jgrid.checkedout', $i, $item->editor, $item->checkedouttime, 'contacts.', $canCheckin); ?>. Wenn du ebenfalls nicht jedem das Freigeben erlaubst, sieh dir die Implementierung incom_contactan, sprich den Code, der$canCheckin` berechnet.

Teste deine Joomla-Komponente

  1. Installiere deine Komponente in Joomla! Version 4, um sie zu testen:

Kopiere die Dateien im administrator Ordner in den administrator Ordner deiner Joomla! 4 Installation.
Kopiere die Dateien im components Ordner in den components Ordner deiner Joomla! 4 Installation.
Kopiere die Dateien im media Ordner in den media Ordner deiner Joomla! 4 Installation.

  1. Die Datenbank ist geändert worden, so dass es erforderlich ist, sie zu aktualisieren. Öffne den Bereich System | Information | Database, wie in Teil 16 beschrieben. Wähle deine Komponente aus und klicke auf Update Structure.

Joomla! Published

  1. Öffne ein Item in der Bearbeitungsansicht.
  2. Wechsele in einen anderen Browser und versuche, das Item erneut zu bearbeiten.
  3. Vergewissere dich, dass du ein Symbol siehst, dass dich darauf hinweist, dass dieses Item gesperrt ist und dass ein berechtigter Benutzer die Sperrung aufheben kann.

Joomla! Sperren/Freigeben

Geänderte Dateien

Übersicht

Vor oder zurück ...