Ich bitte um Entschuldigung, dass ich wieder auf Englisch geschrieben habe, kann meinen Betrag leider nicht mehr editieren (ich weiß auch nicht warum).
Beiträge von Ulricus
-
-
Hi, I have meanwhile worked on this topic with the following result:
I implemented my own router, see code below, but now I do not know how to register it correctly.
This is the router:
PHP
Alles anzeigen<?php /** * @package Joomla.Site * @subpackage com_easyfpu * * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace RuethInfo\Component\EasyFPU\Site\Service; \defined('_JEXEC') or die; use Joomla\CMS\Application\SiteApplication; use Joomla\CMS\Categories\CategoryFactoryInterface; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Component\Router\RouterView; use Joomla\CMS\Component\Router\RouterViewConfiguration; use Joomla\CMS\Component\Router\Rules\MenuRules; use Joomla\CMS\Component\Router\Rules\NomenuRules; use Joomla\CMS\Component\Router\Rules\StandardRules; use Joomla\CMS\Menu\AbstractMenu; use Joomla\Database\DatabaseInterface; /** * Routing class of com_content * * @since 4.0.0 */ class Router extends RouterView { /** * Flag to remove IDs * * @var boolean */ protected $noIDs = false; /** * The app * * @var DatabaseInterface * * @since 4.0.0 */ private $app; /** * EasyFPU Component router constructor * * @param SiteApplication $app The application object * @param AbstractMenu $menu The menu object to work with * @param CategoryFactoryInterface $categoryFactory The category object * @param DatabaseInterface $db The database object */ public function __construct(SiteApplication $app, AbstractMenu $menu, CategoryFactoryInterface $categoryFactory, DatabaseInterface $db) { $this->app = $app; $params = ComponentHelper::getParams('com_easyfpu'); $this->noIDs = (bool) $params->get('sef_ids'); $easyfpu = new RouterViewConfiguration('easyfpu'); $easyfpu->setKey('id'); $this->registerView($easyfpu); parent::__construct($app, $menu); $this->attachRule(new MenuRules($this)); $this->attachRule(new StandardRules($this)); $this->attachRule(new NomenuRules($this)); } public function preprocess(&$query) { if (!isset($query['Itemid'])) { $query['Itemid'] = $this->app->input->getInt('Itemid'); } } }
Then I found some tutorial on how to register this router in my provider.php:
PHP
Alles anzeigen<?php defined('_JEXEC') or die; use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface; use Joomla\CMS\Extension\ComponentInterface; use Joomla\CMS\Extension\MVCComponent; use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory; use Joomla\CMS\Extension\Service\Provider\MVCFactory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\CMS\Component\Router\RouterFactoryInterface; use Joomla\CMS\Extension\Service\Provider\RouterFactory; return new class implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 2.0.0 */ public function register(Container $container): void { $container->registerServiceProvider(new MVCFactory('\\RuethInfo\\Component\\EasyFPU')); $container->registerServiceProvider(new ComponentDispatcherFactory('\\RuethInfo\\Component\\EasyFPU')); $container->registerServiceProvider(new RouterFactory('\\RuethInfo\\Component\\EasyFPU')); $container->set( ComponentInterface::class, function (Container $container) { $component = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class)); $component->setMVCFactory($container->get(MVCFactoryInterface::class)); $component->setRouterFactory($container->get(RouterFactoryInterface::class)); return $component; } ); } };
In line 36, I try to register the router, however, this function (setRouterFactory) does not exist. So how do I correctly register my router?
-
OK, ich habe den Link oben gelesen und dann noch diesen:
https://github.com/joomla/joomla-cms/discussions/35621
Das scheint tatsächlich die Ursache für meine Problem zu sein, zumindest liest sich das so.
Aber ich stecke nicht so tief drin in Joomla 4, dass ich wüsste, an welcher Stelle ich jetzt die empfohlene public function preprocess(&$query) implementieren sollte.
Die relevanten Teile meiner default.php, wo die Links erzeugt werden, sehen wie folgt aus:
PHP
Alles anzeigen// No direct access defined('_JEXEC') or die; // Imports use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Router\Route; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Language\Text; HTMLHelper::_('formbehavior.chosen', 'select'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?> <form action="<?php Route::_('index.php?option=com_easyfpu&view=easyfpus'); ?>" method="post" id="adminForm" name="adminForm"> <!-- The food list --> <table class="table table-striped table-hover"> <thead> <tr> <th width="1%"> <?php echo Text::_('COM_EASYFPU_NUM'); ?> </th> <th width="2%"> <?php echo HTMLHelper::_('grid.checkall'); ?> </th> <th width="95%"> <?php echo HTMLHelper::_('grid.sort', 'COM_EASYFPU_EASYFPUS_NAME', 'name', $listDirn, $listOrder); ?> </th> <th width="2%"> <?php echo HTMLHelper::_('grid.sort', 'COM_EASYFPU_ID', 'id', $listDirn, $listOrder); ?> </th> </tr> </thead> <tfoot> <tr> <td colspan="4"> <?php echo $this->pagination->getListFooter(); ?> </td> </tr> </tfoot> <tbody> <?php if (!empty($this->items)) : ?> <?php foreach ($this->items as $i => $row) : $link = Route::_('index.php?option=com_easyfpu&task=easyfpu.edit&layout=edit&id=' . $row->id); ?> <tr> <td> <?php echo $this->pagination->getRowOffset($i); ?> </td> <td> <?php echo HTMLHelper::_('grid.id', $i, $row->id); ?> </td> <td> <a href="<?php echo $link; ?>" title="<?php echo Text::_('COM_EASYFPU_EDIT_EASYFPU'); ?>"> <?php echo $row->name; ?> </a> </td> <td align="center"> <?php echo $row->id; ?> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> <input type="hidden" name="task" value=""/> <input type="hidden" name="boxchecked" value="0"/> <input type="hidden" name="filter_order" value="<?php echo $listOrder; ?>"/> <input type="hidden" name="filter_order_Dir" value="<?php echo $listDirn; ?>"/> <?php echo HTMLHelper::_('form.token'); ?> </form>
In Zeile 44 wird der entsprechende Link generiert. Muss ich jetzt einen eigenen Override zu /libraries/src/Router/SiteRouter.php kreieren und dort preprocess() implementieren?
-
Hallo bembelimen , was genau meinst Du mit Router? Und was muss ich da aktualisieren?
-
Sorry, Elwood, irgendwie war ich gerade so im Englischen...
Ich habe leider keinen "Bearbeiten"-Button im Originalbeitrag. Nur unter meinen Antworten
Hier ist der Link zum neuen Post, falls es jemand interessiert:
BeitragAuflösung von Links ist anders
Hallo, ich versuche gerade, eine lokale Kopie meiner HP von J3 auf J4 zu migrieren. Dabei stoße ich auf ein Problem mit der Auflösung von Links in einer meiner eigenen MVC-Komponenten.
Dort habe ich eine Liste mit Einträgen, die man durch Anklicken editieren kann. Dabei wird ein neues Template namens "edit.php" aufgerufen. Hier ist der Aufruf im Quelltext:
$link = Route::_('index.php?option=com_easyfpu&task=easyfpu.edit&layout=edit&id=' . $row->id);
In Joomla 3 wurde dieser Link aufgelöst nach
…Ulricus12. Dezember 2021 um 12:16 -
Hallo, ich versuche gerade, eine lokale Kopie meiner HP von J3 auf J4 zu migrieren. Dabei stoße ich auf ein Problem mit der Auflösung von Links in einer meiner eigenen MVC-Komponenten.
Dort habe ich eine Liste mit Einträgen, die man durch Anklicken editieren kann. Dabei wird ein neues Template namens "edit.php" aufgerufen. Hier ist der Aufruf im Quelltext:
$link = Route::_('index.php?option=com_easyfpu&task=easyfpu.edit&layout=edit&id=' . $row->id);
In Joomla 3 wurde dieser Link aufgelöst nach
https://.../index.php/de/easyfpe/easyfpe-web/easyfpe-app?view=easyfpu&layout=edit&id=15
In Joomla 4 wird er aufgelöst nach
https://.../index.php/de/component/easyfpu/?view=easyfpu&layout=edit&id=15
Leider führt diese Auflösung dazu, dass ein falscher Seiten-Stil angewendet wird. Wenn ich den ursprünglichen Link in die Browseradresszeile kopiere, funktioniert es genauso wie es sollte.
Wie bekomme ich alte Linkauflösung wieder hin? Die SEO-Einstellungen sind auf beiden Seiten identisch (Suchmaschinenfreundliche URL ja, alles andere nein).
Vielen Dank!
-
I meanwhile digged deeper and found the route course for the issue. As it has nothing to do with Templates, I will post it in a new threat. This can be closed.
-
Hallo, ich versuche gerade, meine Homepage als lokale Kopie von J3 auf J4 zu migrieren. Ich habe eine eigene MVC-Komponente laufen, das ich ebenfalls auf J4 migriert habe. Auf einer jungfräulichen J4-Version läuft es auch einwandfrei. Bei der migrierten Version allerdings stimmt etwas mit der Zuweisung der Stile nicht.
In meiner Live-Version auf J3 sowie in der lokalen und migrierten J4-Version wird folgende Liste dargestellt, aus der der Benutzer dann ein Essen auswählen kann (anklicken) zum Bearbeiten:
Der Link zum Bearbeiten der Bratwurst (id=2) auf meiner Live-Webseite lautet wie folgt:
https://rueth.info/index.php/de/e…ayout=edit&id=2
Der Link auf meiner lokalen Kopie wie folgt:
http://localhost/joomla-34/inde…ayout=edit&id=2
Auf meiner Live-Webseite nutzt Joomla 3 dann das den Default-Style und das Bearbeitungsformular wird korrekt angezeigt.
Joomla 4 nutzt leider für den gleichen Link einen speziellen Style, der keinen Content anzeigt, dadurch wird das Formular nicht angezeigt.
Ich nutze das Helium-Template. Der Default-Stil sollte eigentlich "Helium - Standard - ..." sein. Leider springt J4 aber mit o.g. Link auf den Stil "Helium - EasyFPE - ...":
Was macht J4 das anders als J3, dort habe ich dieselben Stile verwendet und es hat problemlos funktioniert.
Vielen Dank!
-
Hallo, ich suche eine Erweiterung, mit der ich einfach die An- bzw. Abwesenheit von Chormitgliedern abfragen kann. Ich will dazu "Events" (Auftritte) anlegen und jedes eingeloggte Chormitglied soll mit Ja/Nein/Weißnochnicht seine Anwesenheit eintragen können. Ist so ähnlich wie Doodle.
Hat jemand gute Vorschläge? Möglichst gratis, zumindest nicht zu teuer.
Danke!
-
Danke, Harmageddon, ich override jetzt die validate-Funktion in meiner Model-Klasse wie folgt und es funktioniert nun wunderbar:
Code
Alles anzeigen/** * Method to cast the form data into the types expected by the database. * * @param Form $form The form to validate against. * @param array $data The data to validate. * @param string $group The name of the field group to validate. * * @return array|boolean Array of filtered data if valid, false otherwise. * * @since 0.11.0 */ public function validate($form, $data, $group = null) { // First validate the data, then - if valid - cast them if ($validData = parent::validate($form, $data, $group)) { $castData = array(); // The data seem to be valid, so now cast to expected types foreach($validData as $k => $v) { switch ($k) { // If 'id' is 0 it's a new record, so leave it away, // the 'amount_...' fields are optional, so also leave away if empty, // otherwise these values are int case 'id': case 'amount_small': case 'amount_medium': case 'amount_large': if ($v != '' && $v != '0') $castData[$k] = (int) $v; break; // 'carbs' and 'calories' are float type case 'calories': case 'carbs': $castData[$k] = (Float) $v; break; // All other values: pass them on 1:1 default: $castData[$k] = $v; } } return $castData; } else { return false; } }
Danke für den Hinweis!
-
Hallo zusammen,
ich habe evtl. einen Bug im MysqliDriver.php gefunden, bin mir aber nicht sicher, könnte auch ein Fehler meinerseits sein. In Joomla 3 hat derselbe Code aber funktioniert. Version ist Alpha12. Folgendes Verhalten:
- Ich habe ein Formular mit teilweise optionalen, daher leeren Werten, siehe Screenshot. Rechts sieht man mein Table-Objekt $object mit den drei leeren Werten "amount_..." rot eingerahmt. Ich befinde mich in MysqliDriver.php, Funktion insertObject.
- Nun laufe ich durch die foreach-Schleife bis zur Auswertung des Wertes amount_small. Folgender Code ist das:
Code
Alles anzeigen// Iterate over the object variables to build the query fields and values. foreach (get_object_vars($object) as $k => $v) { // Skip columns that don't exist in the table. if (!array_key_exists($k, $tableColumns)) { continue; } // Only process non-null scalars. if (\is_array($v) || \is_object($v) || $v === null) { continue; } // Ignore any internal fields. if ($k[0] === '_') { continue; } // Ignore null datetime fields. if ($tableColumns[$k] === 'datetime' && empty($v)) { continue; } // Prepare and sanitize the fields and values for the database query. $fields[] = $this->quoteName($k); $values[] = $this->quote($v); }
- Am Ende der Schleife, bei // Prepare and sanitize ..., werden alle Werte mit Hochkommata umgeben. Auch leere Werte, aus denen wird "''", siehe folgenden Screenshot:
- Wird nun die Query ausgeführt, kommt folgende Fehlermeldung von der Datenbank:
Incorrect integer value: '' for column 'amount_small' at row 1
Hier noch meine Datenbankdefinition:
Code
Alles anzeigenCREATE TABLE `#__easyfpus` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) NOT NULL DEFAULT '0', `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', `name` VARCHAR(100) NOT NULL, `favorite` BOOLEAN NOT NULL DEFAULT FALSE, `calories` FLOAT NOT NULL DEFAULT '0.0', `carbs` FLOAT NOT NULL DEFAULT '0.0', `amount_small` int(11) DEFAULT '0', `amount_medium` int(11) DEFAULT '0', `amount_large` int(11) DEFAULT '0', `comment_small` VARCHAR(100) NOT NULL, `comment_medium` VARCHAR(100) NOT NULL, `comment_large` VARCHAR(100) NOT NULL, `published` tinyint(4) NOT NULL DEFAULT '1', `params` VARCHAR(1024) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE =InnoDB AUTO_INCREMENT =0 DEFAULT CHARSET =utf8mb4 DEFAULT COLLATE =utf8mb4_unicode_ci; SET sql_mode = '';
Ist dort ggf. etwas falsch eingestellt?
Vielen Dank für Eure Hinweise!
-
Danke, astrid , das war es tatsächlich! Ich hatte in meinem Namespace das Wörtchen "EasyFPU" - nun alles geändert auf "Easyfpu" und alle Dateien umbenannt...
Lokal arbeite ich auf einem Mac, Server ist tatsächlich Linux. Wundert mich, dass es lokal funktioniert hat, wo doch Mac auch auf Unix basiert.
Also: Nochmals vielen Dank!
-
Hallo zusammen, ich konnte mein Problem nun eingrenzen. Ich habe meine Komponente auf dem Server installiert und dann per Akeeba 1:1 auf meinen localhost übertragen. Während die Komponente auf dem localhost anstandslos startet, findet die MVCFactory-Funktion getClassName meine View nicht. Hier die Funktion:
Code
Alles anzeigenprotected function getClassName(string $suffix, string $prefix) { if (!$prefix) { $prefix = Factory::getApplication(); } $className = trim($this->namespace, '\\') . '\\' . ucfirst($prefix) . '\\' . $suffix; if (!class_exists($className)) { return null; } return $className; }
In beiden Installationen wird der korrekte Klassenname gebildet, nämlich
$className=RuethInfo\Component\EasyFPU\Administrator\View\Easyfpus\HtmlView
Auf dem Server liefert class_exists($className) aber false zurück, während die Klasse auf dem localhost gefunden wird.
Ich vermute, das hat irgendetwas mit Pfaden zu tun. Nun meine Fragen:
- Wie finde ich heraus, in welchen Pfaden gesucht wird?
- Sollte auf dem Server der Pfad fehlen, obwohl der Programmcode absolut identisch ist, wie kann ich sicherstellen, dass meine Views doch gefunden werden?
Danke für Eure Hilfe!
-
firstlady , bitte entschuldige meine missverständliche Art zu kommunizieren, ich habe das Thema zumindest vorläufig abgeschlossen, weil ich wohl erst mal eine stabilere J4 abwarten sollte und mich außerdem mit Hilfe von Astrids Tutorial von vorne heranpirschen sollte statt eine recht komplexe Komponente umzustellen.
Debug-Modus und Entwickler-Reporting sind natürlich aktiv.
Wenn ich ein spezifischeres Problem habe, melde ich mich wieder. Geholfen habt Ihr alle mir aber, vielen Dank dafür!
-
astrid , vielen Dank, ich denke auch, dass ich hier nicht unbedingt weiterkomme, wenn ich alles auf einmal versuche. Mittlerweile habe ich ein weiteres völlig rätselhaftes Problem: Auf meiner lokalen Entwicklungsumgebung (MAMP) läuft die Komponente im Backend einwandfrei, wenn ich sie auf einen Server aufspiele, kommt eine Fehlermeldung. Wenn ich die Serverversion per Akeeba 1:1 wieder in eine neue lokale Umgebung einspiele, tritt der Fehler nicht auf... Da soll einer durchblicken...
Danke für den Link auf Dein github-Projekt, das schaue ich mir auf jeden Fall gut an! Und warte dann auf die Beta-Version.
-
Nix. Daher nutze ich die Router-Klassen ja auch nicht.
Mein Problem ist, dass die Komponente nicht startet, siehe ursprünglicher Post.
-
... diese Routing-Klassen aus dem Tutorial nutze ich gar nicht. Dachte die sind optional, denn er schreibt ja auch, dass er damit eine eigene SEF URL generieren will, die nicht Standard ist. Das brauche ich nicht. Habe eigentlich unverändert meine default.xml aus dem J3 Code übernommen.
-
Hallo, ich stelle gerade eine größere Komponente auf J4 um. Das Tutorial https://docs.joomla.org/J4_Component_example_-_Mywalks hat mir dabei schon gut geholfen. Die Admin-Seite läuft mittlerweile. Jetzt habe ich aber das Problem, dass die Komponente im Frontend nicht startet.
So sieht mein default.xml aus:
Die Auswahl erscheint auch korrekt beim Anlegen eines Menüs:
Im Frontend erscheint aber der Link nicht korrekt, sondern führt zur Homepage, siehe roter Pfeil:
Und wenn ich den Link manuell eingebe (siehe URL), erscheint ebenfalls die Startseite:
Irgendwas scheint mit dem Routing nicht zu klappen. Hat jemand einen Tipp, was ich falsch mache?
Danke!
-
Gelöst!
Ich hatte einen Bug in meinem Modul-Code. Ich entschuldige mich dafür, dass Dich das Zeit gekostet hat, Harmageddon , und bedanke mich sehr für Deine Hilfsbereitschaft!!
-
Hallo!
tatsächlich - wenn ich die Instanzen in eine vorhandene Modulposition (bei mir: footer) durch Menüzuweisung auf zwei verschiedenen Seiten lade, funktioniert es einwandfrei, d.h. die Parameter werden korrekt gesetzt.
Das Modul ist ein selbst geschriebenes, hier noch in der Version für Joomla! 3:
https://extensions.joomla.org/extensions/ext…elds/eventlist/
Hier meine Module:
Und so versuche ich, die beiden Instanzen in einem Artikel zu laden:
(a) mit loadposition:
{loadposition Kleingruppen_Regeltermine} im einen Artikel und{loadposition Regeltermine} im zweiten Artikel.
Verhalten wie im initialen Post beschrieben.
(b) mit loadmodule:
{loadmodule mod_eventlist,Regeltermine Kleingruppen} bzw.
{loadmodule mod_eventlist,Regeltermine}
(so heißen die Module analog den Positionen in (a))
(c) mit loadmoduleid:
{loadmoduleid 120} bzw.
{loadmoduleid 115}