Jump to content

MarkE

Members
  • Posts

    921
  • Joined

  • Last visited

  • Days Won

    10

Posts posted by MarkE

  1. I'm wondering if this is a bug. To test it simply put the following into the Tracy console (replacing 114 with the id of a template in your database):

    $q = $templates->getLoadQuery("id=114");
    d($q);
    d($q->getQuery());

    This generates the SQL query:

    'SELECT templates.id,templates.name,templates.fieldgroups_id,templates.flags,templates.cache_time,templates.data  
    FROM `templates`  
    WHERE id=:s0X 
    ORDER BY templates.name '

    instead of WHERE id=114

    Interestingly, the method WireSaveableItems::getLoadQuerySelectors() includes the following comment:

    		// Note: ProcessWire core does not appear to ever reach this point as the
    		// core does not use selectors to load any of its WireSaveableItems

    which makes me wonder how well tested the use of selectors in this context is...

  2. I am writing a method that extends WireSaveableItems (via a hook) to get a fresh item from the database. What I have so far is this:

    	public function getFreshSaveableItem($event) {
    		$saveables = $event->object;
    		/* @var $saveables WireSaveableItems */
    		$item = $event->arguments(0);
    		$database = $this->wire()->database;
    		$sql = $saveables->getLoadQuery()->getQuery();
    		$query = $database->prepare($sql);
    		$query->execute();
    		$rows = $query->fetchAll(\PDO::FETCH_ASSOC);
    		$freshItem = null;
    		if($item) {
    			$items =  new WireArray();
    			foreach ($rows as $key => $val) {
    				if ($val['id'] == $item->id) {
    					$row = $rows[$key];
    					$freshItem = $saveables->initItem($row, $items);
    				}
    			}
    		}
    		$saveableItems = array();
    		foreach($items as $saveable) {
    			$saveableItems = $saveableItems + $saveable->getArray();
    		}
    		$freshItem->setArray($saveableItems);
    		$event->return = $freshItem;
    	}

    This works, except that where there are multiple matching rows (e.g. for fieldgroups), they are returned in the wrong order. This is because the rows include other fieldgroups and the sort order is 'sort' which will have duplicates because of the multiple fieldgroups.

    To eliminate this problem, I wanted to put the selector inside the query - so that, if the item id is 168, it adds 'WHERE id=168' to the query. I implemented this by replacing

    $sql = $saveables->getLoadQuery()->getQuery();

    with

    		$selector = "id=" . $item->id;
    		$sql = $saveables->getLoadQuery($selector)->getQuery();

    Unfortunately, these seems to generate the query 'WHERE id=:s0X' and I get a PDO exception 

    SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':s0X 
    ORDER BY sort'

    I'm afraid my PDO/SQL skills are a bit limited, so I'm not quite sure what is causing this or how to fix it. I'm hoping someone with some higher-order PDO skills can help!

    If it's any use, I did a bd() for the generated query and attach the Debug info and Full object images below.

    602621383_Screenshot2023-08-05152342.png.6829744bc676ab2d7b62c9bed15d9457.png330779642_Screenshot2023-08-05152432.png.d8ce59fdcbeb1c1c879b673851c6c1f8.png

  3. 2 hours ago, MarkE said:

    LazyCron hook I created which updates related fields

    This raises a question that I hadn't previously considered:
    LazyCron is triggered by a guest action. In my use case, some resulting edits should be shown as edits (i.e. not 'quiet'), but showing the user as 'guest' is a bit misleading. So I put the following in my LazyCron hook:

    /************
     * Batch run
     ************ */
    /**
     * Batch run hooked by LazyCron:
    .....
     */
    function batchRun(HookEvent $e) {
    	$batchRunUser = (wire()->users->find("name=batchRun")->first()) ?: wire()->users->add('batchRun');
    	wire()->users->setCurrentUser($batchRunUser);
    .....

    This seems to do the trick. Is this practice OK, or might there be unwanted side-effects?

  4. 22 hours ago, wbmnfktr said:

    PageHitCounter had this issue in an early version... so page hits resolved in an update BUT... that was long ago. 

    Running ProcessChangelog shows that it is connected with PageHitCounter, but is from a LazyCron hook I created which updates related fields, without specifying 'quiet' 😳

    • Like 2
  5. 9 hours ago, bernhard said:

    How did you archive them?

    Maybe that was a slightly ambiguous wording, for brevity's sake. The detailed description is that some of the pages are events which are now in the past. These are no longer accessible via any links on the website, but the page url still works, which made me think that it might be some kind of web crawler accessing them.

  6. I seem to have a few pages which show they have been modified recently by 'guest'. However, they appear to be unchanged and the related templates have set guest access to view only. I thought it might be something to do with page hit counters, but that seems not to be the cause. Some of the pages are only archives and are not directly accessible from the website (i.e. can't be retrieved by following links from the home page), so it seems a bit like a bot, but surely it should not mark the pages as modified? Any ideas?

    • Like 1
  7. Did you try snippets in Windows?  No need to save, it is automatically put in the screenshots folder which you keep open, so just snapshot it, edit as required and drag. When done, delete all the contents of your folder. Ok so that’s one more step than ideal, but at no development effort!

  8. Thanks @bernhard  I use RockFrontend and am fairly happy with that approach, although I would prefer to say which template to add, for example, favicon to (e.g. my settings template). 
    Re the new logo field. Would that be accessible elsewhere in the API? I sometimes use the logo in other places than just the admin masthead. 

  9. 1 hour ago, bernhard said:

    I'd be interested what you mean exactly by "in this way"? Can you please describe this in more detail?

    I mean adding a field to a pre-existing template. My preferred approach is that modules may add templates and fields, but not automatically modify existing ones - that should be left to the webmaster or superuser, whether directly via setup or via module settings. Also, any new templates and fields should have names that are unlikely to conflict, e.g. by using an appropriate prefix. 

  10. 14 hours ago, bernhard said:

    What if AdminStyleRock created a logo field for you and placed it on the home template? Would that be what you want? You could then also move it to your dedicated settings page.

    Interesting thought. I'm not too keen personally on modules modifying the database in this way. Another approach would be to have a page ref field and a field with the name of the image field. That said, the solutions suggested above work well anyway. Having tried both of them I am marginally inclined towards @BitPoet's solution as the entry in the module settings is clear and it seems a bit more 'Processwiry'.

  11. 12 hours ago, BitPoet said:

    Code for settings template:

    <?php namespace ProcessWire;
    
    if($input->urlSegment(1) === 'logo') {
    	wireSendFile($page->logoimage->filename, [
    		'exit'		=>	true
    	]);
    }

    Then just put /path/to/settings/page/logo/ into the logo image file field.

    That's a really neat trick - useful in a bunch of other contexts too!

    So 2 great solutions from @BitPoet and @Markus Thomas - spoilt for choice (and I will get back to @bernhard with ideas too). 😀

  12. 1 hour ago, Markus Thomas said:

    I set the imagepath in AdminTheme to: '/site/assets/files/1020/be-logo.svg' (1020 is my settingspage)

    I did think of that, but with multiple installations I am not confident that the id of the settings page will be identical. Maybe I’m just being overly cautious. 

  13. The standard admin themes (UI, Rock etc) permit you to modify the logo by giving a path to it. I would like to be able to specify the logo as being an image field on a settings page? I know I could do this with a fairly ugly hack using regex in a hook on Page::render, but I wonder if there is a better way?

  14. 4 hours ago, flydev said:

    About multisite, I think yes, but I have never personally tried, so others will answer to it. 

    I have tried multi site and there are pros and cons, chiefly:

    Pros - only one core codebase to maintain ( & smaller footprint, but at less than 30mb, that's not such an issue)

    Con - All your sites need to run on the same PW (and PHP) version. Sometimes, you may be ready to upgrade one site, but not another.

    On balance, I now tend to go for a different PW install for each site.

    • Like 4
  15. 8 hours ago, wbmnfktr said:

    Future-Proof Setup: ProcessWire 3.0.210 (or latest stable), PHP 8.1

    I am still getting a deprecation warning with that combo.

    Quote

    Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/wire/core/WireInput.php on line 371

    I think it is caused by the cookie module MarkupCookieConsent passing an explicitly null param, but it should be caught by the cookie() method in WireInput. Easily fixed by changing line 371 to

    if($key === null || !strlen($key)) return $this->cookieVars;

    Worth a PR?

    • Like 1
×
×
  • Create New...