Jump to content

BitPoet

Members
  • Posts

    1,126
  • Joined

  • Last visited

  • Days Won

    47

BitPoet last won the day on July 9 2020

BitPoet had the most liked content!

5 Followers

Profile Information

  • Gender
    Male
  • Location
    Near Munich / Germany
  • Interests
    programming, writing, scuba diving, long distance hiking

Recent Profile Visitors

7,631 profile views

BitPoet's Achievements

Hero Member

Hero Member (6/6)

2.6k

Reputation

27

Community Answers

  1. You'd need to turn Event and EventArray into modules programmatically, i.e. add "implements Module" to the class declaration and add the static getModuleInfo() method. The returned array from that method is where you can set the autoload value. Then you can also drop the require_once() statements in the fieldtype's constructor. (And don't forget to install Event and EventArray Modules in the backend after the change)
  2. I'm not sure I'd go down that road, even though it's probably possible. For one, you can't take advantage of the logic already there for numeric field types. For two, what if there are additional price scales? To round it up, for three, it may speed up input, but there will likely be cases where you'll have to disassemble the unformatted value anyway to present the information. I'd go with a repeater that has fields for quantity and price (maybe a default price field on the item page and just add scale prices in the repeater). That way, your data is queryable through selectors, your code will be easier to understand years later when you have to come back and make changes, and you don't have to worry about multiple scales for one item. Price calculation will be just a small piece of code: $price = $item->price; foreach($item->scaleprices->sort('-quantity') as $scale) { if($order->quantity >= $scale->quantity) { $price = $scale->price; break; } }
  3. Have you tried calling $modules->get('yourfieldtype') before using the API? To avoid that, you could turn Event and EventArray into autoload modules.
  4. The wrong is on the side of the module. Too much has changed in the standard datetime field, and I didn't have the time to catch up with these changes. You'll probably have to remove the field and module by hand on the database level (there could be easier ways, but the exact approach probably depends on the exact PHP and PW versions). drop the table field_[yourfieldname] execute the query "DELETE FROM fields WHERE type = 'FieldtypeDatetimeAdvanced';" execute the query "DELETE FROM modules WHERE type = 'FieldtypeDatetimeAdvanced';" delete the module directory Sorry for the hassle. I have added a notice to the module's readme. Unfortunately, I won't find the time to adapt the module before the end of the year.
  5. In site 1, I'd guess that there's a spot where you're missing quotes in $_SERVER['HTTP_HOST'] (i.e., $_SERVER[HTTP_HOST], which will with strict mode turned off interpret HTTP_HOST as the name of a constant in the current namespace). The error in site 2 points to a missing pdo_mysql extension, so make sure that it's activated and enabled in php.ini.
  6. I think we've talking past each other a bit, so let me see if I can word it differently. The cache should never return an expired value, but I can understand that the strange behavior in your tests 5 and 6 suggests differently. If you don't want to lose a value, don't let it expire. Instead, put the logic to overwrite the cached value with a newer one when your API call is successful into your code. And perhaps store the last retrieval time in your cached value, so you have the creation timestamp you mentioned. Perhaps code says more than a thousand words: <?php /** * Code for Cron Job */ $apiResult = your_api_call(); $cachedResult = json_decode($cache->get('yourcachekey'), true); if($apiResult) // Only if API call was successful if(!$cachedResult || $cachedResult['created'] < time() - 300) { // Cache entry older than 5 minutes, write new value to cache $cache->save('yourcachekey', json_encode(['created' => time(), 'apiResult' => $apiResult], WireCache::expireNever); } } /** * Code for frontend use of API data */ $cachedResult = json_decode($cache->get('yourcachekey'), true); $apiResult = $cachedResult['apiResult']; if($apiResult['created'] < strtotime('-1 month')) { // Deal with a stale cache value that hasn't been updated in over a month here }
  7. Nice overview! For full fledged field types, you'll often also want to implement Fieldtype::getConfigAllowContext and Inputfield::getConfigAllowContext. They return an array with the names of those config fields defined in their respective getConfigInputfields method that may be overridden in template or fieldgroup context. The Inputfield class by default returns these config fields: return array( 'visibility', 'collapsed', 'columnWidth', 'required', 'requiredIf', 'requiredAttr', 'showIf' ); So make sure to call parent::getConfigInputfields first, then add your own config inputs. A good example is how InputfieldText does this: public function ___getConfigAllowContext($field) { $a = array('initValue', 'pattern', 'placeholder', 'maxlength', 'minlength', 'required', 'requiredAttr'); return array_merge(parent::___getConfigAllowContext($field), $a); } Now the initValue, pattern, placeholder, maxlength, required and requiredAttr settings can be overridden in each template the field is used in.
  8. In that case, the most straight forward approach is to add a custom permission through the backend (e.g. 'import-pages'), hook before your module's execute method and check if the current user has this permission. Untested code for site/ready.php: <?php namespace ProcessWire; wire()->addHookBefore("ImportPagesCSV::execute", function(HookEvent $event) { if(wire('user')->isSuperuser() || wire('user')->hasPermission('import-pages')) return; $event->return = '<h3>You do not have permission to import pages. Please contact the administrator!</h3>'; $event->replace = true; }); Of course, this still leaves the backend menu item in place, but unlike modifying third party modules, it is upgrade safe.
  9. The word "tag" is very a technical thing. Call them "keywords" instead, and more than half of your users' questions will evaporate instantly. That's what I learned at my current job when I trained colleagues and heard the relieved insight, "Oh, you're talking about keywords!" rather often. The other half you'll only catch with real-life examples. Depending on the number of pages and content editors, it might make sense to moderate keywords for a while until everybody got their footing. Just a small Pages::published hook that sends a backend link to the new page to the tags moderator so they can give the chosen tags a once over and clarify with the editor what makes sense and what doesn't. I did that with a small knowledge base section for our technical sales managers when they went into a new market area, and we used the direct feedback to fill the tags (later keywords) FAQ with examples and explanations that made sense to them. Actually, that's no longer the case. Since 3.0.177, you can use the new InputfieldTextTags, and choosing a delimiter other than space will allow multi word tags.
  10. As a hobby writer, I do have my doubts there. Natural language is the second most ambiguous thing in the world, right after Schrödinger's cat.
  11. Why don't you split your cron job's logic to use two separate cache calls? $cache->get('cachetest') to read your cached data without expiring it, and $cache->save('cachetest', '+1 month', $apiresult) only if your api call was successful. You'll always have the last successful call's result in your cache this way, and it will be much cheaper than full fledged pages.
  12. I'd say it's just a question of a missing "echo" in front of page()->render('callout');
  13. The short answer is: don't use a lifetime in calls to $cache->get(). Somewhat longer: it looks like a bug to me. It certainly doesn't do what the docs say, namely check the age of an entry. The behavior is a bit different if you specify a template function as the third value, as that uses the lifetime to fill the cache with the function's return value, but that's neither here nor there. In your case (unless I'm misinterpreting what you wrote), the only call that needs a lifetime is the one to $cache->save() in your cron job. The other parts can just call $cache->get('cachetest') and be happy (unless the cache wasn't updated within the last month).
  14. is_callable doesn't resolve namespaces. It should work if you use "ProcessWire\\custom_debug_if". I'm not sure why ProcessWire.php doesn't use wireIsCallable() at that spot. Might be worth raising an issue.
×
×
  • Create New...