Jump to content

BitPoet

Members
  • Posts

    1,331
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by BitPoet

  1. Can you elaborate on that? I only know short circuit evaluation from programming languages / algorithms, and there it is a conscious efficiency or safety measure where you use "AND" in conditions to avoid unnecessary calls or expressions in later conditions, like preventing division by zero dumps by making sure the divisor is not zero in "if($count > 0 && $price / $count > $limit)". I can't imagine a scenario where a PW selector expression does not follow the basic laws of boolean algebra though. There should never be side effects caused by the order of selectors in a PW selector expression.
  2. The round braces in selectors are named OR-groups for a reason, so you'll have to adapt your selector. You may want to remove the negation and switch ">" to "<=" and "<" to ">=" for easier readability. Since I don't really know how maps to your data, it's difficult to tell you more. The docs I linked also explain to use named OR-groups where at least one selector expression of each named group has to match. To apply that to your example, this would e.g. read: $pages->get("parent=1042, first=(!comp0_min_high>200, !comp0_max_override<100), second=(!comp1_min_high>50, !comp1_max_override<10), third=(!comp2_min_high>50, !comp2_max_override<10)"); However, if your logic is right, you can simply drop the parentheses since boolean AND expressions are commutative. (a AND b) AND c is the same as a AND b AND c or c AND b AND a.
  3. Yes. And since - unless I'm reading you wrong - you update those two addresses with two seperate forms, you should have two independent page fields, which will save you from all kinds of headaches. Since addresses are so similar, you can use the same field type with all necessary fields for each of the addresses and only include those fields in your form that apply to the address type. That way, you'll avoid all the headaches that come with updating just one of the addresses without overwriting the values of the other.
  4. You might reach a point where table level locks kill (some of) the speed improvements of caching if you are using MyISAM as the database engine. In that case, switching to InnoDB might speed things up, though you'll lose a small bit of that in insert/update performance itself. I have a site with about the same number of cache entries that runs fine (using InnoDB). When the row count gets noticeably larger, using Memcached (or any other in-memory key-value storage) gives marked performance improvements, but that is of course only possible if you can run the necessary daemon software on the server.
  5. I'd save keystrokes and struggles by unifying billing and shipping addresses into one single address fieldtype (you don't have to use the vat column if you are processing a shipping address, or the department if it's the other). Then you can add separate "shipping" and "billing" fields of the same type to your page and don't risk clearing one of those if you process the form for the other. I've taken the liberty to amend the four most verbose methods using that approach: <?php /** * Get the database schema for this field * * @param Field $field In case it's needed for the schema, but usually should not. * @return array */ public function getDatabaseSchema(Field $field) { $schema = parent::getDatabaseSchema($field); $schema['data'] = 'TEXT NOT NULL'; // user last name $schema['data_firstname'] = 'TEXT NOT NULL'; $schema['data_gender'] = 'TEXT NOT NULL'; $schema['data_company'] = 'TEXT NOT NULL'; $schema['data_vatid'] = 'TEXT NOT NULL'; $schema['data_street'] = 'TEXT NOT NULL'; $schema['data_zipcode'] = 'TEXT NOT NULL'; $schema['data_city'] = 'TEXT NOT NULL'; $schema['data_country'] = 'INT(10) UNSIGNED'; $schema['data_department'] = 'TEXT NOT NULL'; // Remove index from data column unset($schema['keys']['data']); return $schema; } /** * Any value will get sanitized before setting it to a page object * and before saving the data * */ public function sanitizeValue(Page $page, Field $field, $value) { if(!$value instanceof Address) $value = $this->getBlankValue($page, $field); if ( $value->isChanged('company') || $value->isChanged('gender') || $value->isChanged('vatid') || $value->isChanged('firstname') || $value->isChanged('lastname') || $value->isChanged('street') || $value->isChanged('zipcode') || $value->isChanged('city') || $value->isChanged('department') || $value->isChanged('country') ) { $page->trackChange($field->name); } return $value; } /** * Get raw data values from database and perhaps adjust data for $page output * */ public function ___wakeupValue(Page $page, Field $field, $value) { if(empty($value) ) return false; // get blank $address = $this->getBlankValue($page, $field); $value['country'] = $this->pages()->get( (int)$value['data_billing_country'] ); $value['block'] = (string)$value['data_company'] . PHP_EOL . (string)$value['data_firstname'] . ' ' . (string)$value['data'] . PHP_EOL . (string)$value['data_street'] . PHP_EOL . (string)$value['data_zipcode'] . ' ' . (string)$value['data_city'] . PHP_EOL . (string)$country->title; $address->setArray($value); return $address; } /** * * Add mapping to different name for use in page selectors * This enables us to use it like "field.min=10, field.max<=200, field.graduation>10" */ public function getMatchQuery($query, $table, $subfield, $operator, $value) { if ($subfield == 'city') $subfield = 'data_city'; if ($subfield == 'company') $subfield = 'data_company'; if ($subfield == 'country') $subfield = 'data_country'; if ($subfield == 'department') $subfield = 'data_department'; if ($subfield == 'firstname') $subfield = 'data_firstname'; if ($subfield == 'gender') $subfield = 'data_gender'; if ($subfield == 'lastname') $subfield = 'data'; if ($subfield == 'street') $subfield = 'data_street'; if ($subfield == 'vatid') $subfield = 'data_vatid'; if ($subfield == 'zipcode') $subfield = 'data_zipcode'; return parent::getMatchQuery($query, $table, $subfield, $operator, $value); }
  6. You can't, without running into major headaches, change the root page (i.e. "Home"). What you can do is create a copy and move all children with the exception of the system fields (admin, trash, 404) under the new home. Then you can adapt the Home page to your liking (i.e. switch template, edit contents, whatever). Here's a small script that automates that task. This hasn't been tested extensively, so I don't advise to run this on a production system, only on a copy (or at the very least make a test run on a copy and then make sure you have a full, working database backup at hand). You can copy this code into a script (e.g. as "clonehome.php") in your PW installation root and run it from the command line. <?php namespace ProcessWire; if(PHP_SAPI != 'cli') exit; include('index.php'); error_reporting(E_ALL); ini_set("display_errors", true); /* ************************************************************** * CONFIGURATION FOR CLONING * *************************************************************/ $adminUser = "admin"; // PW Backend User $childrenToLeave = [ $config->adminRootPageID, $config->trashPageID, $config->http404PageID = 27 ]; /* ************************************************************** * END OF CONFIGURATION * *************************************************************/ $session->forceLogin($users->get($adminUser)); $home = $pages->get($config->rootPageID); echo "Cloning Home" . PHP_EOL; $newOldHome = clone $home; $newOldHome->setQuietly('_cloning', $home); $newOldHome->addStatus(Page::statusSystemOverride); $newOldHome->removeStatus(Page::statusSystem); $newOldHome->removeStatus(Page::statusSystemID); $newOldHome->id = 0; $newOldHome->setIsNew(true); $newOldHome->parent_id = $home->id; $newOldHome->of(false); $newOldHome->set('numChildren', 0); $newOldHome->removeStatus(Page::statusSystemOverride); $pages->save($newOldHome, ["quiet" => true]); echo "Home page cloned, new id is {$newOldHome->id}." . PHP_EOL; $childrenToLeave[] = $newOldHome->id; echo "Moving children:" . PHP_EOL; // Now move all children, with the exclusion of admin tree and special pages (404, Trash) // as configured in $childrenToLeave foreach($pages->find("parent=$home, include=all") as $child) { if(in_array($child->id, $childrenToLeave)) continue; echo "- {$child->name}..."; $child->of(true); $child->parent = $newOldHome; $child->save(); $child->of(true); echo "[X] Done" . PHP_EOL; } echo "FINISHED. All children moved." . PHP_EOL;
  7. That shouldn't happen, but you should be able to see what went wrong either in the http server's error log or in the PHP log. My first guess would the standard template's PHP code, but it could be a lot of things.
  8. "Internal Server Error" or "Page Not Found"? The latter is what you should be seeing for inaccessible files, and that's the correct thing for ProcessWire to do according to HTTP standards. If you see an internal server error (status code 5xx), something's wrong. For a "Page Not Found" error, PW renders the "404 Not Found" page under "Home" unless you have configured a different page as $config->http404PageID in site/config.php. You can create your own error page template and change to that in the page properties to adapt the output and make it more dynamic.
  9. Have a look here:
  10. Deleted, I somehow answered to an old post.
  11. Since you have an array(ish) $clearPages, it looks like you want to recreate the cache for depending pages too (blog categories/tags pages etc.?) so I'd guess you'd have to make a request for each of those. It might become a runtime issue if you have multiple complex pages to render, but the worst that could happen is that rendering breaks at some point and the first request to an uncached page is slower.
  12. You want to write that line: $mobile_menu = $homepage->children; in one of a few different ways, e.g.: $mobile_menu->add($homepage->children); // or, though no need to create a new PageArray beforehand in this case: $mobile_menu = $homepage->children->makeCopy(); to avoid any caching issues and avoid changing "builtin" PageArrays. If you directly assign $homepage->children, $mobile_menu points to the already loaded instance of the children PageArray of $homepage and your new, empty PageArray gets discarded. Repeated calls to $pages->get(1) are cached and return the page object already in memory. I can only guess since you didn't post that part of the code, but it looks like you may have inadvertently manipulated $homepage->children when you built your main navigation. Make sure to use add() or makeCopy() in that part too.
  13. That's strange. The code works fine here (3.0.132). Can you take a look into the pages table and compare the entry for id 92871 with a working user (parent_id, templates_id, status)?
  14. I was thinking of combining the two. Have a toplevel Media Library somewhere and let ImageReference pull its images from that. Though I'm not familiar enough with the latter to judge if that would be a working solution.
  15. You should be able to replace the try/catch block with this if clause, but this is untested (I'm not using the module anywhere): $imgSmart = $page->get(implode('|', $configData['imageSmart'])); if($imgSmart instanceof WireArray) { $pageData['image'] = $imgSmart->first()->httpUrl; } else { $pageData['image'] = $imgSmart->httpUrl; }
  16. Have a look at @apeisa's Redirects module. This lets you configure arbitrary paths and pages they should redirect to.
  17. Looks to me (untested) like you shouldn't have images.description but rather description only in your selector, since you're already operating on the images themselves, and images themselves have no template (you have already limited the parent page in your $pages->find call to that). $match->images->find("description~=$keywords"); should be enough.
  18. You could either use the fork by esl51 or incorporate the fix yourself (changing the "count" in line 245 to "!empty"). Maybe someone actively using the module could talk with @Nico Knoll about maintining the module on GitHub? There's already a pull request that fixes this waiting in the repo.
  19. That might actually be something @ryan could implement in the standard with a module config setting for ProcessLogger. So how about a pull request for that? ?
  20. Ah, that's the ugliness of Repeater magic once more. Inside the FieldsetPage, the field's name and id change from crondate to crondate_repeaterXXXX (where XXXX is the number of the fieldsetpage item) to prevent collisions. The hook probably should check against preg_match('^/crondate(_repeater\\d+)?$/', $field->name) instead of a straight comparison to work both inside and outside a repeater/fsp. Not exactly sure how the JS part is addressed best.
  21. Have given Media Library a look?
  22. You could adapt and try out the code in this post:
  23. If you can live with the fact that a counter is inserted into the filename, I'd copy the file to a temp path, then add that to sender_logo_standard and remove the temporary copy after the page was saved. There's a possibility to intercept the hook method that performs the file system level deletion with your own prioritized hook, but doing so is not completely free of side issues since the original hook removes itself, with doesn't happen if intercepted. Another idea that comes to mind is wrapping your replacement fields inside a FieldtypeFieldsetPage. This will be editable just like a regular fieldset in the page, though for api access, you have one more level of indirection, i.e. $single->sender_log_standard_changes would become something like $single->changes->sender_logo_standard_changes (but you might re-use the sender_logo_standard there instead of having two different fields, so it could be $single->changes->sender_logo_standard). The advantage is that $single->changes would be a different page behind the scene. The moment you add the image from there to your regular image field, PW sees that this belongs to a different page and creates a copy.
  24. Ah, now it makes sense (and no sense for templates), no idea how that slipped past me. Thanks a lot! I removed the warning in version 0.0.3.
  25. That's a good question which I don't have an answer to. I copied that from ProcessField, which behaves the same - a warning if you use "manage tags", but none if you assign such a tag in the regular Field edit form. Good point, thanks. Already added in 0.0.2.
×
×
  • Create New...