Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by BillH

  1. Here you go! You need to decide how big each batch will be and set the $startPage and $endPage values each time you run the script. For example, if you have 1230 pages and decide to run the script three times you could use 0 and 499; 500 and 999; 1000 and 1300. Note that you should start at 0 (because the indexing of the page array starts at 0). And it's OK if the last number is larger than the total number of pages. Note also that I haven't tested the code, so let me know if it doesn't work! <?php // If you put the script in /site/ this is OK (otherwise you may need to amend) include("../index.php"); // Change these two values for each batch $startPage = 0; $endPage = 499; // Change the selector to match your pages $selectedRecords = $wire->pages->find("template=my-template"); echo "Pages with images: " . count($selectedRecords) . "<br/>"; $pageCounter = 0; $recordsProcessed = 0; foreach($selectedRecords as $thisRecord) { $pageCounter += 1; if (($pageCounter >= $startPage) && ($pageCounter <= $endPage)) { echo $thisRecord->title . "<br/>"; $recordsProcessed += 1; if(count($thisRecord->article_images)) { $thisRecord->of(false); foreach($thisRecord->article_images as $image) { $description = $image->description; $credit = $image->credit; $image->photo_caption = $description; $image->photo_credit = $credit; $thisRecord->save('article_images'); } $thisRecord->save(); } } } echo "<p>Records processed: {$recordsProcessed}</p>"; ?>
  2. I'd definitely try @netcarver's suggestion first. And if that doesn't work, you could try putting this after saving the record, though I'm not sure if it will make a difference: $pages->uncacheAll(); Then if you still have the problem, for a one-off task you could split the processing into batches. Doing something like the following is highly inefficient, but simple and will definitely work – and is probably more efficient than spending a lot of time trying to find a better fix! $startPage = 0; // Manually change this for each batch $endPage = 1000; // And this too $pageCounter = 0; foreach($pageToProcess as $thisPage) { $pageCounter += 1; if (($pageCounter >= $startPage) && ($pageCounter <= $endPage)) { // Process $thisPage here } }
  3. The script should be a standalone PHP file, not placed in a template. So, for example, you might name the script "fix-images.php" and put the file in /site/. Then, if you normally access the site at https://www.mysite.com, run the script by accessing https://mysite.com/site/fix-images.php . For more details, take a look at this page (particularly the last section): https://processwire.com/docs/front-end/include/
  4. I did exactly the same thing a year or two ago. Here's the script I used (I've simplified the selector and a couple of other things, and added one comment). The script moves the image description and the ImageExtra field 'credit' to the new 'photo_caption' and 'photo_credit' fields. I don't know if you're familiar with running such scripts, but you simply put the script somewhere on your server and enter its URL in your browser. It might be a good idea to test with the saves commented out. <?php // Amend depending on where this script file is located include("../index.php"); $selectedRecords = $wire->pages->find("template=my-template"); echo "Pages with images: " . count($selectedRecords) . "<br/>"; $recordsProcessed = 0; foreach($selectedRecords as $thisRecord) { echo $thisRecord->title . "<br/>"; $recordsProcessed += 1; if(count($thisRecord->article_images)) { $thisRecord->of(false); foreach($thisRecord->article_images as $image) { $description = $image->description; $credit = $image->credit; $image->photo_caption = $description; $image->photo_credit = $credit; $thisRecord->save('article_images'); } $thisRecord->save(); } } echo "<p>Records processed: {$recordsProcessed}</p>"; ?> This was written for a one-off task, so I did nothing to refine it, but it worked. Note that at the time both saves were necessary, though I think this has been resolved now and, depending on which version of PW you are running, you may be able just to save the whole record - but it'd probably be easier to leave it as it is!
  5. If you create a page reference field named 'recipe_category' and want to find everything in the category 'soup', you could do something like this: $categoryPage = $pages->get("name=soups"); $soups = $pages->find("template=recipes, recipe_category=$categoryPage"); Alternatively, if you could use a select options field (easier to set up, but less flexible and harder to change anything, so usually page reference fields are better in the long run): $soups = $pages->find("template=recipes, recipe_category.title=soups");
  6. I don't know the cause of the trouble, but it might be worth checking that your .htaccess file is being read by adding some random characters at the start; a server error when you go to a page of the site will mean that it is being read. My best guess about the /assets/files/ errors is that .htaccess is being read, and that the errors are a side effect arising from the rewrite rules involving that directory. Have you looked inside the PW .htaccess? It's well commented, so the next thing might be to read through it for any ideas.
  7. I think this will tell you what you need:
  8. You could use a hook as in this discussion: Putting the hook in ready.php may well be a good plan.
  9. Regarding users, what you describe is a common situation with membership systems, where there are often things such as corporate members with associated members, so it might be worth searching the forums to see if there's anything about what others have done. And perhaps take a look at the Login Register Pro module. For file uploads, in one project that requires regular uploads by a client, I made a simple admin page containing only a file field (giving me an instant UI) and a Save button. I hooked after the page has saved to process the files. I don't know of a better idea for matching files to clients than using filenames – though that doesn't mean there isn't one! I have one suggestion: it might help to reduce errors if the filename included a checksum for the string that identifies the client.
  10. You may get them in the correct order (that is, the order they appear in the page tree) by default. But if you don't, try adding `sort=sort` to your selector - see "How to force pages to sort by their admin order" on the page https://processwire.com/docs/selectors/).
  11. Another possible approach, given $subchildren as the result of your find: $parent = null; $grandparent = null; foreach($subchildren as $subchild) { $scParent = $subchild->parent; $scGrandparent = $scParent->parent; // Or $subchild->parent->parent if($grandparent != $scGrandparent) { $grandparent = $scGrandparent; echo $grandparent->name . '<br/>'; } if($parent != $scParent) { $parent = $scParent; echo '&emsp;' . $parent->name . '<br/>'; } echo '&emsp;&emsp;' . $subchild->name . '<br/>'; } Obviously, this'll produce simple indented text, but you could adapt to generate a list or whatever you need.
  12. I suggest taking a look at the sections 'Finding pages that have specific parents or ancestors' and 'Sub-selectors: selectors within selectors' of the 'Using Selectors' page at https://processwire.com/docs/selectors/. You might end up with something a little like this, here finding all grandchildren with a name beginning with 'a' that have a grandparent with location = 'US': $grandchildren = $pages->find("has_parent=[template=grandparent, location=US], name^=a");
  13. And another thought: consider using URL segments as described at https://processwire.com/docs/front-end/how-to-use-url-segments/.
  14. Recently I was planning a project for an archive of PDFs, and I decided that a page per PDF was going to be significantly easier to work with and more flexible than grouping them in file fields. The number of pages shouldn't be a problem. You'd get around 6k pages a year, so 60k a decade, 120k after two decades... Comfortably within PW's capabilities. On the other hand, a client page with a file field holding 500 PDFs after a decade doesn't sound great! If you haven't seen it, you might find something interesting in this recent blog post about new scalability options: https://processwire.com/blog/posts/pw-3.0.175/
  15. Hi @Goca and welcome to the forums! There's a useful description of how templates work at https://processwire.com/docs/start/templates/ Don't miss the link to the pages about output strategies in the 'Next steps' section at the end. Note that if you'll have a lot of pages where each needs a slightly different template, you may find that the best approach is for them to share a template containing a little conditional logic, for example: if($page->name == 'page1') { // Display something } elseif($page->name == 'page2') { // Display something else } elseif...
  16. What happens when you try "Check again"? The same message, error 500 or something else? If error 500, there's probably something in .htaccess that your server doesn't like. It might be worth installing a fresh .htaccess, just in case an error has crept in. Other than that, if you've tried everything in the discussion mentioned above, this starts to go beyond my knowledge!
  17. If you haven't found it, this discussion might help:
  18. To set a cache that will expire at midnight today: // Expiry time string $midnight = 'today 23:59:59'; // Alternatively, the start of tomorrow is midnight today // $midnight = 'tomorrow'; // Save the cache $cache->save('test-cache', 'Value for cache', $midnight); So, to achieve what you want (if I understand you correctly), you could use the get() method something like this: $midnight = 'tomorrow'; $str = $cache->get('test-cache', $midnight, function() { return "The next cache value"; }); By the way, if you haven't discovered it, the getInfo() function is really useful for debugging, for example: print_r($cache->getInfo(false, 'test-cache'));
  19. The phrase you quote ("Optionally specify...") comes from the doc page for $cache->get(). With this function, you are specifying the maximum age of the cache you are trying to get (for example, up to 3600 second old). I could be misunderstanding you, but it sounds as if you're trying to set the expiry time for caches that you have created, in which case use $cache->save(). Or perhaps that is what you're using, in which case follow the instructions for the expire argument on the relevant page (https://processwire.com/api/ref/wire-cache/save/). Note: if you want them, the WireCache::expire constants are on the $cache page (https://processwire.com/api/ref/wire-cache/).
  20. Hi Iraklis, and welcome to the forums! I can't entirely figure out what's going on from your description, but here's some information that may give you a foothold. PW has two types of field ("fieldtypes") for selection options, and it sounds as if you may be dealing with the second of these: Select Options, where the options available are defined on the Details tab of the field definition. Page Reference, where each option is set up as a page, and you select the page. The page could be a page that appears on the site, but it could be something as simple as a name (e.g. the name of a country) used only as an option for selection (and doesn't appear as a page on the site). This seems a little odd at first, but it's a powerful and flexible way of doing things! You'd find the pages somewhere in the page tree, either under Admin or somewhere else - e.g. you might have Value Lists > Countries > Afghanistan etc. To find out which type of field you're dealing with: Setup > Fields > Your field > Basics tab > Type. To find out what template a page is using: Your page > Edit > Settings > Template. You'll find template files in Site > Templates. Let us know if you need further help.
  21. A couple of good discussions about understanding output formatting:
  22. Have you looked at the structure of the PW database? If not, it's quite easy to understand, and you may find that storing comments would be a lot "cleaner" than you expect. Essentially, the data for each field is held in a separate table, so the comments would be quite distinct from other data. If you'd be happy with the database structure, it'd at the very least save you what I imagine would be a huge amount of work!
  23. I'm sure it'll be mentioned in the posts you'd find following @bernhard's link, but I'd draw your attention to another module also worth looking at: https://processwire.com/modules/batch-child-editor/ - particularly the Add mode, which can import CSV.
  24. The post from @Robin S deals with your issue nicely, I think, but it might also be worth a look at the links in this discussion: The ConnectPageFields module uses methods similar to the synchronization suggested by @Pixrael. And owner selectors look interesting, though I've never tried them.
  25. I'm not sure what you're aiming at, but is it that you want to find pages based on both what is in the portfolio-detail page and in the user page? If so, one approach might be to do something like this (not tested): $userIDs = implode('|', $pages->findIDs("template=user, title%=sometext")); $profiles = $pages->find("template=portfolio-detail, user_id={$users}, another_field%=someothertext");
  • Create New...