Leaderboard
Popular Content
Showing content with the highest reputation on 09/20/2024 in all areas
-
I mentioned a couple of weeks ago that I’ve got to do a lot of traveling in September and October, and so that means not a lot of core updates in the short term. Core activity may be a little quiet till the end of October. Sorry about that, I feel especially bad I’m not providing any good material for ProcessWire Weekly. But I’ll make up for it later, I promise! I’ve been reluctant to push any significant updates to the core because it is quite stable right now. So I’ll hold off on anything major till the traveling is done. I did just push one update to the dev branch that I think is a good addition though. I noticed recently that on a couple sites I work with, there was some markup cached with $cache that never seemed to expire. I tracked it down to an issue in WireCacheDatabase where some caches had ended up with invalid MySQL dates somehow or another. WireCacheDatabase now implements its own cache maintenance that ensures these never-expiring caches get deleted. In doing that, the cache maintenance process became more efficient as well, as it’s all handled with a single delete query, rather than multiple select and delete queries. If you’ve been noticing anything cached by $cache that doesn’t seem to be expiring when it should, it’s worth grabbing the current dev branch, or at least the updated /wire/core/WireCacheDatabase.php file from the current dev branch. One way you can tell if you have any caches that shouldn’t be sticking around are if you find any with dates prior to the year 1971, or any with a zero’d out date like 0000-00-00. Maybe there is still a bug to track down that is causing the occasional invalid dates, but at least now those caches won’t last more than 10 minutes. There likely won’t be an update here next week, as I’m anticipating no internet access, but there should be the week after next. Thanks for reading, have a great week and weekend!11 points
-
3 points
-
I'm just going to quote myself to make sure that you read my response: I'm a software developer that built and maintains a module for ProcessWire, not a Google product specialist. Please stop asking me to do your work for you.3 points
-
Sometimes the best thing you can do for the project you work hard on is to get away from it for a while. When you come back, you'll notice a lot of new shining edges (or the ones to be polished) and almost definitely have lots of new shining ideas about it. So please do this little PW detox to keep it new and sparkling for yourself and all of us!2 points
-
Thanks @bernhard for that video. This puts a name on the concept I have used a bunch of times and I think is the only real way to solve OPs problem. Most ERP systems and also some well-known e-commerce systems out there (I know of Shopfiy and Shopware which do that) don't let you manage an item's quantity with a simple text field or a simple "number". Instead, the quantity is "event sourced" (as in the video) with a log of changes. This even includes the initial value. The video also says it, but as an example, one could come up with the current item's stock quantity of 8 by looking at this "event log": +10 from incoming shipment -2 from order -1 from order +3 from incoming shipment -1 from order -1 from order In ProcessWire, you could create a repeater to achieve this. Just record all your "incoming" lines with a repeater in your product (remember to add a datetime field) and add hooks to orders which automatically add lines when orders are placed/refunded/cancelled. The only remaining thing is to modify the repeater editor to only allow the user to edit new items. But a combination of limiting edit access to the entire repeater and a "update quantity" field like @bernhard and @da² suggested will get you there.2 points
-
@SIERRA I use Google Cloud services for some things but I'm not really an expert on it. I can provide some information that I am familiar with but you'll need to do research to determine if it fits your needs. I built a module that interfaces with a Google service but it doesn't provide any special insights. I'll start off with the easy answers first. Yes. Fluency translates the content that you enter into ProcessWire into other languages using the third party service, then enters that translated content into ProcessWire which is then stored in your website's database. This is stored the same way as if you had manually entered the content in other languages yourself. Even if you translated content for your website and then uninstalled Fluency altogether your translated content is stored in ProcessWire and is yours to keep. Third party translation services almost always, as far as I've seen, charge by character count. This is because words and phrases may be different lengths in different languages. It's not really possible to guess ahead of time what your character count will be according to word count, the best way to determine that is to translate some content then check your Google Cloud account to see how many characters you have used and then come up with an estimate based on that information. See my note below on using Google's tools to estimate this. Yes. ProcessWire's language support adds tabs to each multi-language field. If you manually add content to the fields under each tab and don't use Fluency to perform translation then you will have not used any translation service credits. That said, consider the following: Here you can see that Fluency is set up with the "Translate to all languages" option configured. This means that if you have entered content in any language and click "Translate to all languages", Fluency will translate that content into all of the other languages and then replace anything that has been already been entered under other language tabs. This is intentional behavior. If you use this option and have already added content that you are satisfied with in another language, then clicking "Translate to all languages" may be unnecessary because it will translate your content and overwrite it anyway. I'm not able to tell you want to do and I don't want to be responsible for any charges that came about due to bad information on my part. Google provides plenty of information about how they charge for their services and I would just be doing the same research that you would need to do to fit your use case. Google has a pricing calculator that you can use to estimate costs for usage of any Google Cloud services, including translation. Here's the link to check it out. No. Their billing is based on services usage per month so you will only pay for what you use. There isn't really a service that exists, as far as I know of, that would charge a flat fee for "a website" because that could mean a very large website or a very small website. I'll make a couple of recommendations that may help you out in this situation. If this is for a client, then the costs of using third party services are what they are. You don't have control over pricing or how much they ultimately intend to use the service because this is content that they will provide. The estimated content range of 400,000 to 500,000 words is very wide and not accurate. That range is 20% and won't be accurate, especially considering that the charges are in characters and not words which each have different character counts . To put this into context, a quick search found that the average length of a novel is 40,000 to 70,000 words long. That means the difference between the two word counts in your case is anywhere from 1-2 entire books you'd find at a book store- that isn't trivial! The best idea is to work on getting accurate pricing is to try and get a much more accurate estimate on length of content. Book publishers would not accept a 100,000 give-or-take estimate from an author in how long a novel is because there are real costs involved, and the same would best be true in this case. Here's a few things that you may be able to do: If you have all of the content ahead of time, then get an accurate character count and pad it a little to get a price you can work with. If you have some of the content, but not all, take estimate the percentage that content is relative to the entire amount of content, get the character count, and multiply it. If you estimate that you have 10% of the content right now, get the character count and multiply that by 10, then add a little to be safe, and estimate your costs. If the website will list products, or blog posts, or something that repeats, estimate the amount of content for one and then multiply that by an estimate of the number of whatever will be repeated on the site. It's much easier to estimate the content for one item of many and then estimate the number of how many there will be. If you already have a few examples, get the character count for each and calculate the average before multiplying. Hope that helps. Just trying to offer some advice that may be useful.2 points
-
@ryan enjoy the extended break from work, although it is something you love it needs to be done1 point
-
Seconding this, of course! However, the WireCache fix reminded me of an old issue that still persists as far as I can tell 😉 No upvotes, but still feels like a bug to me: https://github.com/processwire/processwire-issues/issues/1604 It’s about the preloading feature preventing fresh cache values from being generated.1 point
-
My too I'm happy Linux user. I actually tried many years ago to make my Hackintosh, but, luckily, didn't work and I moved from Mac to Linux and never regret it. The freedom you have is priceless. My distro of choice: https://www.bunsenlabs.org/ very clean and stable, based on Debian. As for Adobe, yes, still miss a proper app for Linux. I now use https://affinity.serif.com/ on a dual boot Windows machine. Affinity does pretty much what Adobe does, but it has a reasonable price. File manager: Thunar does the job, but if you want to have fun try Midnight Commander!1 point
-
Hey @BrendonKozand @poljpocket, I just wanted to update that I have used ddev based on your suggestions and scripts and it's great. Thanks again for sharing that info and those configurations. I had been using MAMP pro (trial) but when the trial expired, the free version didn't work for some reason. I gave ddev a try with MariaDB, and it worked great. Thank you both for that suggestion. I didn't get to test Lightspeed but I think it'll probably be fine. 🤞 Thanks again!1 point
-
Search Corrections Suggests alternative words for a given input word. This can be useful in a website search feature where the given search term produces no results, but an alternative spelling or stem of the term may produce results. The module has two methods intended for public use: findSimilarWords(): this method suggests corrected spellings or similar alternatives for the given word based on words that exist in the website. stem(): this method returns the stem of the given word, which may give a full or partial match for a word within the website. The module doesn't dictate any particular way of using it in a website search feature, but one possible approach is as follows. If a search produces no matching pages you can take the search term (or if multiple terms, split and then loop over each term) and use the module methods to find alternative words and/or the stem word. Then automatically perform a new search using the alternative word(s), and show a notice to the user, e.g. Your search for "begining" produced no matches. Including results for "beginning" and "begin". findSimilarWords() This method creates a list of unique words (the "word list") that exist on the pages and fields that you define, and compares those words to a target word that you give it. The method returns an array of words that are sufficiently similar to the target word. For multi-language sites, the $user language determines which language populates the word list. Similarity The method ranks similar words by calculating the Levenshtein distance from the target word. Where several results have the same Levenshtein distance from the target word these are ordered so that results which have more letters in common with the target word at the start of the result word are higher in the order. Method arguments $target (string) The input word. $selector (string) A selector string to find the pages that the word list will be derived from. $fields (array) An array of field names that the word list will be derived from. $options (array) Optional: an array of options as described below. minWordLength (int) Words below this length will not be included in the word list. Default: 4 lengthRange (int) Words that are longer or shorter than the target word by more than this number will not be included in the word list. Default: 2 expire (int) The word list is cached for this number of seconds, to improve performance. Default: 3600 maxChangePercent (int) When the Levenshtein distance between a word and the target word is calculated, the distance is then converted into a percentage of changed letters relative to the target word. Words that have a higher percentage change than this value are not included in the results. Default: 50 insertionCost (int) This is an optional argument for the PHP levenshtein() function. See the docs for details. Default: 1 replacementCost (int) This is an optional argument for the PHP levenshtein() function. See the docs for details. Default: 1 deletionCost (int) This is an optional argument for the PHP levenshtein() function. See the docs for details. Default: 1 Example of use // The input word that may need correcting $target = 'dispraxia'; // Get the Search Corrections module $sc = $modules->get('SearchCorrections'); // Define a selector string to find the pages that the word list will be derived from $selector = "template=basic-page"; // Define an array of field names that the word list will be derived from $flds = ['title', 'body']; // Optional: override any of the default options $options = ['maxChangePercent' => 55]; // Get an array of similar words that exist in the pages/fields you defined // The return value is in the format $word => $levenshtein_distance $results = $sc->findSimilarWords($target, $selector, $flds, $options); Example result: stem() This method uses php-stemmer to return the stem of the given word. As an example, "fish" is the stem of "fishing", "fished", and "fisher". The returned stem may be the original given word in some cases. The stem is not necessarily a complete word, e.g. the stem of "argued" is "argu". If using the stem in a search you will probably want to use a selector operator that can match partial words. Method arguments $word (string) The input word. $language (string) Optional: the language name in English. The valid options are shown below. Default: english catalan danish dutch english finnish french german italian norwegian portuguese romanian russian spanish swedish Alternatively, you can use the ISO 639 language code for any of the above languages. Example of use // The input word $word = 'fishing'; // Get the Search Corrections module $sc = $modules->get('SearchCorrections'); // Get the stem of the word $stem = $sc->stem($word); https://github.com/Toutouwai/SearchCorrections https://processwire.com/modules/search-corrections/1 point
-
1 point
-
Hi everybody, I have inherited the website of our dance association. We also use Process Wire with Recurme. I encountered a fatal error when updating from PHP7.4 to PHP8.3. I could fix it by fixing this function. I added the check "is numeric". Maybe it can be helpful for somebody else. public function ___formatDate($date = '', $format = 'U'){ // default to time() if($date === '' || $date === null){ $date = time(); } // date is integer set_error_handler(function() { /* ignoring e_warning on date fail */ }); if(is_numeric($date)){ $date = $date; } else if(strtotime($date)){ $date = strtotime($date); } else{ restore_error_handler(); return false; } return date($format, $date); } Best Regards Florian1 point
-
AFAIK ProcessWire’s pagefileSecure feature only works on the page level. So when your page is viewable by guests, its files will be viewable as well. However, when pagefileSecure is active, all files should be routed through the hookable method ProcessPageView::___sendFile(). It’s a short little method you could hook to add your own logic. For example: $this->addHookBefore('ProcessPageView::sendFile(template=MY_SPECIAL_TEMPLATE)', function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); $filename = $event->arguments(1); if ($this->wire->user->isGuest()) throw new Wire404Exception('File not found', Wire404Exception::codeFile); });1 point
-
You could always add your own stylesheet in /site/init.php like this: $this->addHookAfter('ProcessController::execute', function (HookEvent $event) { $this->config->styles->append("/site/templates/css/adminstyles.css"); });1 point
-
Just a follow up here for those who haven't found the Github issue: https://github.com/processwire/processwire-issues/issues/1952 It looks like the next version of Apache (2.4.63) will include a fix (https://github.com/apache/httpd/commit/a1a93beb58b81f1de2b713ae5f96c41ed5952a74) that should hopefully prevent this from being an issue for PW.1 point
-
Turns out I can reproduce a forbidden error by simply loading a URL like http://pwtest.test/about/?id=%3f It seems like you need to view a page that isn't the root url (hence the about child page) and that you have %3f in there. On some servers http://pwtest.test/about/%3f this also returns a 403 but on others I need the %3f to be part of a URL parameter. This Drupal ticket reports the same issue and references the same apache change that Robin noted: https://www.drupal.org/project/drupal/issues/3460799 If I make a similar change to PW's htaccess rule (as was changed in Drupal), ie: change: RewriteRule ^(.*)$ index.php?it=$1 [L,QSA] to: RewriteRule ^(.*)$ index.php [L,QSA] or: RewriteRule ^ index.php [L,QSA] then everything works again. I expected that would break PW's page routing and/or admin, but initially it looks to be OK which honestly seems weird. So other than the issue with UserActivity, we'll all need to be careful if we ever url_encode anything with a question mark (%3F) in it unless @ryan thinks an htaccess change like (or similar) that would be ok. Perhaps it will need some reworking of some of the $GET['it'] related code in PagesRequest.php to handle all scenarios? Also, I just discovered that the server with what I thought was an old version of apache, was actually not old - I almost exclusively run Debian servers, but the "old one" I mentioned is Ubuntu and someone else is managing it now and they did update to 2.4.41 which in Ubuntu world includes that %3f fix: https://launchpad.net/ubuntu/+source/apache2/2.4.41-4ubuntu3.191 point
-
The larger picture of why I'm doing this is to overall De-Google, De-Microsoft and De-Apple my life as much as possible (surely there will be exceptions). It's not about saving money or privacy (those are very very minor points), but personal optimization, control, me being ready for it, Linux desktop having become really great in the last X years, and taking a stronger liking to FOSS and self-hosting.1 point
-
Well, I don't understand why, but saving the title in a discrete operation separate from other fields seems to work. In other words, this works for everything except the title: $product->of(false); $product->foo = 'bar'; $product->baz = 'yadda'; // ...etc... $product->title = 'hmm'; // does not work $product->save(); Whereas this seems to work for everything including the title: $product->of(false); $product->foo = 'bar'; $product->baz = 'yadda'; ...etc... $product->save(); $product->setAndSave(title', 'hmm'); // works fine1 point