-
Posts
375 -
Joined
-
Last visited
-
Days Won
5
Everything posted by da²
-
Hi @brodiefarrelloates Could it come from an outdated module? What says the stack trace? (should be in errors log) In my PW database I don't have any "sessions" table, only a session_login_throttle. EDIT: OK I see it comes from wire\modules\Session\SessionHandlerDB\SessionHandlerDB.module. I have no idea when this module is triggered but you can see in source code the SQL query to create "sessions" table: public function ___install() { $table = self::dbTableName; $charset = $this->wire()->config->dbCharset; $sql = "CREATE TABLE `$table` (" . "id CHAR(32) NOT NULL, " . "user_id INT UNSIGNED NOT NULL, " . "pages_id INT UNSIGNED NOT NULL, " . "data MEDIUMTEXT NOT NULL, " . "ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, " . "ip INT UNSIGNED NOT NULL DEFAULT 0, " . "ua VARCHAR(250) NOT NULL DEFAULT '', " . "PRIMARY KEY (id), " . "INDEX (pages_id), " . "INDEX (user_id), " . "INDEX (ts) " . ") ENGINE=InnoDB DEFAULT CHARSET=$charset"; $this->database->query($sql); }
-
Provide a way to define / save / sync fields in the code base
da² replied to Rasso's topic in Wishlist & Roadmap
@MarkE My approach is a bit different and very basic. I don't plan to migrate pages or anything else than fields and templates configuration, nor to interpret data or use PW API or track user changes with hook, it's just a raw database process. That's why there are more drawbacks and limitations. If one day I need a real migration tool I'll use RockMigrations or ProcessDbMigrate. ? -
Provide a way to define / save / sync fields in the code base
da² replied to Rasso's topic in Wishlist & Roadmap
I'm also interested in this use case, I'm also curious of the feasibility and I need a short "brain pause" from my current project, so I'm trying some experiments for fun. Like @bernhard said this approach have limitations and drawbacks, at least: You must be sure that both databases use same ID for fields and templates (and maybe more like languages...), But if that's not the case, we may fallback on field and template name, except when field/template has been renamed. Nobody can manually change fields and templates on the target installation, Some data can not be updated so easily, like the field type that can require changes on database structure, Maybe some data in "data" column ("fields" and "templates" database tables) can not be changed so easily too (I see for example some "parent_id" properties), Probably more drawbacks... ? But anyway, I find the idea interesting and am having fun experimenting this. Actually I have some bit of code that do 2 things, compare "fields" table from 2 PW installation and display a summary of the changes. Example of output: Next step should be to update database, and adding sanity checks to avoid some kind of changes (like on field type). But I'm not confident at all to use this on a production server before a lot of tests and a confirmation by Ryan and other PW developers that there's not risk updating what I'm gonna update. ? I'm not even sure I'll use it one day, this is actually just experimentation for fun and curiosity. -
But find() searches in current language AND default one. I assume OP wants to search only in one language. https://processwire.com/docs/multi-language-support/multi-language-fields/#how-language-fields-work
-
Accessing $pages through API in another module (LoginRegister)
da² replied to Krit65's topic in API & Templates
@Krit65 Just in case, do you know the common way to translate modules in PW admin? Menu Setup > Languages > Your Language > Find files to translate > Select LoginRegister file > Translate what you need. If it's needed to make translations editable from frontend, I would use PW translator to save phrases. I never used this API, I did a test but I don't know why it's breaking my existing translation file (it removes all previous translations and leaves 'file' and 'textDomain' empty): $language = wire()->languages->getLanguage("english"); /** @var LanguageTranslator $translator */ $translator = wire(new LanguageTranslator($language)); $textDomain = '/site/templates/account-edition.php'; // Domain for LoginRegister should be '/site/modules/LoginRegister/LoginRegister.module' $translator->loadTextdomain($textDomain); $translator->setTranslation($textDomain, 'Logout', 'My translation'); $translator->saveTextdomain($textDomain); // Breaking my existing translation file Another way, closer from what you're trying to do, is to hook one of the LoginRegister methods that build forms and change text values on the fly using your term-translation page, so in ready.php (code not tested): wire()->addHookAfter('LoginRegister::buildLoginForm', function (HookEvent $event) { $terms = $pages->get('template=term-translation'); /** @var InputfieldForm $form */ $form = $event->arguments(0); $myField = $form->getChildByName('Email'); $myField->set('label', $terms->myTranslationField); }); Take care that there are several hookable methods that build a form in this module, ___buildLoginForm, ___buildRegisterForm... (check source code). -
For this part you should use the entity encoded string, actually it opens an XSS vulnerability.
-
Accessing $pages through API in another module (LoginRegister)
da² replied to Krit65's topic in API & Templates
Why not using PW translation mechanism? LoginRegister module is ready to translate, you just have to enable languages support, create a new language, search the LoginRegister module in translations admin page and translate it. You may also find an already prepared language pack for your language (not sure it translates LoginRegister module but maybe, at least you'll get lot of PW translations already done). https://processwire.com/docs/multi-language-support/ -
Yes I see this Apple thing, but it can't show if it's hidden. ^^
-
OK that's because cache is cleared just before the sorted hook callback, but instance given in callback is the "old" one, yes that makes sense when you look at implementation. ^^ Nothing is wrong, that's a long story. Method with children loop is also called by several hooks, including a saveReady, so at first I didn't need to save current page in loop because PW was gonna save it at end. So when I added sorted hook, I saw that I had to save() the page myself so did it in the hook because other method was not doing it, and that didn't worked. Finally I refactored this method to take in parameter if it's needed to save current page.
-
Can't fix it with an overflow:hidden somewhere on a parent div?
-
Yes, sorted hook comes after saveReady one, so I have to do a save() myself (or use saveReady and check the sort change myself). I just reproduced the problem I was talking about in first post: wire()->addHookAfter('Pages::sorted(6019)', onSorted(...)); function onSorted(HookEvent $event): void { /** @var Page $page */ $page = $event->arguments(0); // This code was in another function used by several hooks. // Its job is to update all children in a certain order. foreach ($page->parent->children() as $child) { if ($child->id == $page->id) { $child->title .= "-"; // $child->save(); // Save new title } } // And this code was in the hook callback. $page->save(); // Does not save new title } Saving the instance given by hook is not working, I don't know if it's expected, why cache is not giving both times the same instance?
-
It's getting harder to remember exactly what happened, since code is a bit complex, using multiple hooks, was updated since I posted this topic, and what happens in PW is not totally clear for me. I just checked something in my new code (fixed one), and find that the changes I do to the page (in sorted hook) are not saved if I don't save it myself, even if sorted is followed by saveReady and so page should be saved. This changes are done on the instance returned by find() (children() run on parent page, exactly). Maybe I have a cache issue in my code and should investigate more. And maybe I should try to reproduce this in an easy code. Sure, I never use instances.
-
Provide a way to define / save / sync fields in the code base
da² replied to Rasso's topic in Wishlist & Roadmap
Did you ever think of using fields and templates data directly from database? ("fields" and "templates" tables) On my current project, while the site is still in closed beta I just push my dev database to remote server, so updating is easy. But a time will come when I'll have to replicate my changes without erasing production site. ? I think about testing RockMigrations but I'm also thinking about something more targeted to my main needs: most of the time I'll just add and configure new/existing fields and templates, and it looks like it can be done with "fields" and "templates" database tables. I don't know how ProcessDbMigrate works, I looked the code very quickly and think you parse PW data using API, like RockMigration does if I'm right. Dunno if directly using the database is a good idea, but that looks faster to implement and more robust to me actually because you don't need to take care of future PW features or changes to add them in your JSON exporter/importer. Just sharing some thoughts... -
I don't remember exactly why I thought of getFromCache option, probably cause of this in find() documentation: and this in getById(): But I didn't even specified the key 'loadOptions', and anyway true is default... I had a hard day when I posted this message. ? About cache cleared after save, in a hook when I save a page (other than the one triggering the hook) I use: $page->save(options: ['noHooks' => true, 'uncacheAll' => false]); It's coming from an advice on this forum, section "Page cache issues...". So when I saved the last page I suppose cache has not been cleared, but I didn't investigate more since, I just moved this last save() in the function working on instances found via children() (find()) function. But that may be related with that.
-
But you can still do your own check in this hook, searching another page with same name before to apply unique flag. Then if you find one you can throw an error, or unpublish the page or set another name...
-
@joe_g I thought it was easy to solve with a hook, but there's something strange: I create a page named "test" without unique status, I add a hook that set next pages as unique, I create another page "test" in a different parent, Page is saved without problem with "unique" flag and name "test", even is another page in another parent uses this name, If I remove the hook and try to do the same by manually checking the box: PW denies because another page uses this name. So setting "unique" via a hook doesn't trigger the unique check when saving page, maybe @ryan can help. I used this hook so unique flag is set before saveReady: $this->addHookBefore('ProcessPageEdit::buildForm', function (HookEvent $event): void { /** @var Page $page */ $page = $event->object->getPage(); if ($page->template->name == 'hotlap') $page->addStatus(Page::statusUnique); });
-
Maybe PW version ? I use 3.0.228.
-
@Gideon So I did a test and it works on my side with multiple files, but there's something strange, the first uploaded file always has empty filedata. If I delete all files and upload again it's the same. ? That looks like a bug. Another way would be a hook to set filename into description field.
-
Hi @Roadwolf, where are you adding the link?
-
Hello @joe_g, I see there is a "unique" property in page settings ("Settings" tab > Status), that ensures no other page will use the same name. If you create the page with API, I think this should work: $page->addStatus(Page::statusUnique);
-
Hello @Gideon So, This works: $pages->find('file_field.filedata.uploadName%=230925_213339_R.json');
-
Hello, EDIT: this original post wasn't clear, code in this post is way more explicit to show the thing I'm talking about. I'm not asking how to manage this problem, but is it a bug? And if not, could you explain why this behavior? To make it short: why is the Page instance given by HooEvent->arguments(0) not the same as the one given by find() function (children() here)? Shouldn't it be cached and the same? My use case: I have a method "foobar" called by several hooks. This method process sibling pages of the one received in parameter (using $page->parent->children()), and save the other pages if modified, but does not save the one received in parameter because it can come from a saveReady hook and so the page is already being saved. The problem comes from a Pages::sorted hook, after calling "foobar" method I save myself the page using the Page instance given by hook event ($event->arguments(0))... And so I'm not saving anything because it's not the same instance that was modified in "foobar" method. I know how to manage this, but that looks like a cache bug, isn't it? When "foobar" is called by a saveReady hook, changes are saved, so instance used internally by PW is same as children() one. But when I save with hook instance ($event->arguments(0)), changes are not saved. Here is a kind of demonstration, we can see Page instance from HookEvent is not the same as get() or find(): wire()->addHookAfter('Pages::sorted(6778)', test(...)); function test($event) { $eventPage = $event->arguments(0); $findPage = wire()->pages->find(6778, ['getFromCache' => true])[0]; $getPage = wire()->pages->get(6778); wire()->log->message('$eventPage === $findPage ' . ($eventPage === $findPage)); // False wire()->log->message('$eventPage === $getPage ' . ($eventPage === $getPage)); // False wire()->log->message('$findPage === $getPage ' . ($findPage === $getPage)); // True foreach ($eventPage->parent->children() as $sibling) { if ($sibling->id == $eventPage->id) { wire()->log->message('$sibling === $eventPage ' . ($sibling === $eventPage)); // False wire()->log->message('$sibling === $findPage ' . ($sibling === $findPage)); // True wire()->log->message('$sibling === $getPage ' . ($sibling === $getPage)); // True } } } In PW admin, drag/drop the page of id 6778 to change its sort order, and check "messages" logs. I force getFromCache just to test but it's already default value. Is it the expected behavior? Why? Am I supposed to modify/save the instance from hook event or from find()? Does it even matter?
-
@digitalbricks Checking PHP documentation it's necessary to combine 2 flags, both combinations work: $a = ['a','b','C','A']; sort($a, SORT_NATURAL|SORT_FLAG_CASE); // a, A, b, c sort($a, SORT_STRING|SORT_FLAG_CASE); // a, A, b, c EDIT: cross-posted ?
-
Be careful with $page->meta(), I'm using it for another purpose and it throws if page doesn't exist in DB, so at first page save (after giving a title): ProcessPageAdd: WireDataDB sourceID must be greater than 0 It's necessary to check ID before: if ($page->id) $page->meta(....);
-
@maetmar In site/config.php you can specify your prepend file: // Prepend this file in /site/templates/ to any rendered template files $config->prependTemplateFile = '_init.php';