Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Edison last won the day on July 14

Edison had the most liked content!

Community Reputation

80 Excellent

About Edison

  • Rank
    Jr. Member

Profile Information

  • Location
    Milan, Italy

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Hi @chrizz, personally I load all my custom classes through an autoloader called in config.php. For this purpose you can also consider ready.php. However If the custom class is associated only to a specific module (it will be used only when this module is installed) I think you may consider to load it from within the module itself in init() or ready().
  2. @MilenKo, you need to add the round bracket and semicolon ad the end. The last line must be "});"
  3. Hi @MilenKo, the function closing round parenthesis and semicolon were missing, I have edited it above. Please note I had no time to test it, it may be necessary to tune it
  4. Hi @MilenKo, you could try with an hook in ready.php. In this example Pages:saveReady is called right before the page is saved, so this can be used to fill some fields right before save will be executed. Assumption is that this is triggered when you are saving the page from within the Admin area. $wire->addHookBefore('Pages::saveReady', function($event) { $page = $event->arguments(0); if($page->hasField('date_created')) { $page->date_created = time(); } $event->arguments(0, $page); }); I quickly wrote it in the browser w/o testing Please note, this is more a date_modified as it will be overwritten at the next save, but you can easily make it a "true" date_created, with something like that: if(empty($page->date_created)) $page->date_created = time(); Sorry, of course I thought Linux-wise ... as you have a Windows server when you have sometime have look if php locales are installed.
  5. Hi @MilenKo, I may be wrong but it looks like it's returning a php default locale. It may sound like a stupid question, but are your languages locales installed on your server? If you have access to your server you should check the file /etc/default/locale. Running a sudo cat /etc/default/locale you get the list of installed locales. I am asking that as I recall I had first to install locales on the server before I could use them. The html language directive is normally used by the browser or search engines to classify the page by language, so should not be relevant for this issue. Anyway you may wish to set the proper lang using this code snippet where html is generated: <html lang='<?= wire('user')->language->code ?>'> EDIT: sorry too easy ... the above snippet works if you create the following hook in ready.php: // call it using $user->language->code or wire('user')->language->code or user()->language->code $wire->addHookProperty('Language::code', function(HookEvent $event) { $language = $event->object; $event->return = $language->name === 'default' ? 'en' : $language->name; });
  6. Hi @MilenKo, it's curious strftime is only showing the date in English, it looks like the locale is not switching. Can you test the following for each of your site languages: echo setlocale(LC_ALL, 0); // Will return current locale If locale is properly switching you should see the corresponding locale associated to each language. Regarding the datetime field I can try to put in place a small a tutorial.
  7. Hi @MilenKo, forgotten to mention that formatting date created with strftime() has some limitations, in particular if you need a different date format for each locale you code will get more complex. And if in the future you will have to add a new language you will have to modify your code. I believe you can achieve a more flexible result creating a DateTime field, where you will define the output format for each language. You will then add this datetime field to your template. An hook on pages:saveReady can take care to automatically load your datetime field. Each time you will output it as $page->yourDateTimeField it will be formatted automatically, depending on the locale, as you defined during the field creation.
  8. Hi @MilenKo, I think strtotime() is not needed. $page->created should return a Unix timestamp that you can directly supply to strftime(). This is probably the reason you get 1969's date. I tested the following on my site and it seems to be working. The site is multi-language, and the month is properly returned in both English and Italian, without the need to use setlocale(): echo strftime("%d %B %Y", $page->created); and here is the output: Regarding setlocale() in principle you should not need to set them. May be you can check for each language its individual configuration, in Core Translation Files: And add the locale in the field "C": This should be repeated for every language including default one. Not sure this will help.
  9. Probably creating a custom FieldtypeDataLogger (or how your prefer to name it !) may give you the best of both worlds. You could have your own optimized MySQL table schema, while for post-processing/reporting you could embed it as field in a PW page/pages, where you will access individual data (temperature, humidity, etc..) as properties of the field, and with all the advantages of PW selectors.
  10. Hi @mr-fan, you are dealing with a very interesting project! Wow… it brings me back to my previous lives in Microcontrollers and Nand Flash storage... If your MCU timer is sampling analog data every 10 minutes, and your objective is to store them for 5 years at this granularity level (10 minutes), as you have calculated, it means 2.6*10^5 records. That's not trivial at all. I love PW page-storage capabilities, but, on my personal opinion, resulting storage solution would be less efficient and performant than directly storing data into a MySQL table. I would use MySQL table for data storage and PW pages for data post-processing and reporting. A lot would depend from which kind of post-processing you are going to need, but as you are building a simple (but big!) data logger, another option for storage could be even to create a simple flat file to which you are appending a new record every 10 minutes. However MySQL, in the long run, will give much better flexibility, versatility, and performance. If you wish to look for a simple example of using MySQL from inside PW I suggest you to explore at FieldtypeComments core module. Comments in PW are not made using PW page-storage, but as a MySQL table (field_comments) so you can get some useful hints in dealing with MySQL schemas from within PW. Of course you do not need to create a separated MySQL database for your logger, it can be simply a new table inside your existing PW database, exactly as PW does to manage comments. Please also note that PW library provides an embedded support for dealing with MySQL (I did not use it so far, but .. now I feel I need to make a trial soon…) in $database API variable. By the way, if you need any help to create a MySQL data logger table inside your PW database, just give me the data specs, I would be glad to help you in setting up a trace. Wish you a nice week-end.
  11. Hi @Juergen, what about the following: $y = new Y(); echo $y->addText()->setText(' A B C D '); class X { protected $text = ''; public function setText(string $value = null) { $this->text = trim($value); return $this->text; } } class Y { protected $x; public function __construct() { $this->x = new X(); } public function addText() { return $this->x; } } I have tested it and it is working, however I did not thought about it too much, it may be possible to do something smarter. Wish you a nice week end.
  12. When I installed Processwire for the first time, I noticed that Admin sessions were not lasting for a long time and it was very common to be logged out. Reading this forum I found useful information, but I could not solve this issue. I tried to modify site/config.php adding $config->sessionExpireSeconds with different values, but without success (for your awareness sessionExpireSeconds default value is 86400 seconds, ie 1 day .. so quite enough!). OK, I had no time to go deeper, so I kept doing what I had to do ... being happily logged out … time to time. Few weeks later while studying Session.php in wire/core/ I got the hint (please read the commented text) which helped me to understand how to solve it: if(ini_get('session.save_handler') == 'files') { if(ini_get('session.gc_probability') == 0) { // Some debian distros replace PHP's gc without fully implementing it, // which results in broken garbage collection if the save_path is set. // As a result, we avoid setting the save_path when this is detected. } else { ini_set("session.save_path", rtrim($this->config->paths->sessions, '/')); } } Uh! Yes, my VPS uses Debian 9 ! So I quickly did a test: echo ini_get('session.gc_probability'); echo ini_get('session.gc_divisor'); echo ini_get('session.gc_maxlifetime'); The session.gc_maxlifetime was rightly set to 86400, but session.gc_probability was 0 ! As you can easily get from Session.php routine, if probability is 0 bye bye PHP's session garbage collection and of course PW will not set the save_path. But why probability is set to 0 ?? This is due to the fact Debian/Ubuntu Linux overrides standard PHP’s session garbage collection by setting session.gc_probability to 0. As a consequence PHP’s standard session garbage collection will never run. Instead Debian/Ubuntu sets a specific Cron job for garbage collection with a duration of 1440 seconds, ie 24 minutes. This determines the max session duration. If you try to change session.gc_maxlifetime through $config->sessionExpireSeconds=86400 or ini_set('session.gc_maxlifetime', 86400) it will have no effect and sessions will be deleted at intervals of 24 minutes (or within 54 minutes). The Cron job garbage collection duration is defined at php.ini level, and runtime changes to session.gc_maxlifetime will not affect the Cron job timeout. Uh! Of course the simplest solution would be to change session.gc_maxlifetime in php.ini. However sometimes this is not possible (shared hosting). Another point to consider is that this change may affect multiple applications running on your server. Instead of modifying php.ini, personally I preferred to enable PHP's session garbage collection locally for Processwire only. Majority of the code is already written in PW Session.php, we have just to take benefit of it. Let's go step by step. Let's open site/config.php and do the following modifications (I choose to implement 14400 seconds session time, ie 4 hours): /** * Reduce inactivity timeout (original 86400 = 1 day) * How many seconds of inactivity before session expires */ $config->sessionExpireSeconds = 14400; /** * Enable Session Garbage Collection * Garbage Collection is disabled in Debian as default (probability set to zero) * Enable session garbage collection with a 1% chance of running on each session_start(); * Chance calculated as gc_probability/gc_divisor * Session path is defined inside wire/core/Session.php and points to site/assets/sessions * Thanks to this modification session now takes into account gc_maxlifetime set in config */ ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 100); Do not forget to lock site/config.php after modifying it. Here it is! We are done! After we have set gc_maxlifetime (through sessionExpireSeconds), enabled the garbage collection (gc_probability=1), and set its intervention probability (gc_divisor=100 ie 1% chance), we can rely on Session.php where the a session path (session_save_path()) is defined, and session is started (session_start()). In the development session of our browser let's look for our session cookie: if you go to site/assets/sessions you will find your corresponding session: Please note that during development phase, likely having little traffic, the number of sessions may grow and they will not be deleted. This depends from the 1% chance of deletion. If you want to test garbage collection is properly working or just to make sure sessions files are regularly cleaned during development, you can decrease gc_divisor to a lower rate(10=>10% ... 2=>50%). Do not forget to reestablish gc_divisor = 100 when moving to production. I hope some can find that tutorial useful in the future ... and may save several log outs!
  13. Personally when I install a CMS I prefer to set it inside a subdirectory rather than the root folder. There are different reasons for this choice. For example you may wish to have different CMS installed in different subdirectories; or multiple copies or versions of Processwire in different subdirectories; keep separated directories for production and development; and so on. Sometimes this choice is taken also to obfuscate your CMS contents. In this forum I found some helpful hints, but I could not find a turn-key tutorial explaining the detailed steps for redirection and how to hide subfolder in urls' segments. It's pretty easy. Just let's do it step by step. We are going to create a new .htaccess file in the root folder (please note it is a new one, we will leave the .htaccess file in Processwire subfolder unchanged), where we will add the section described below. Just replace yoursite.com and yoursubfolder with ... your ones! # .htaccess in root directory # Redirect to Processwire subdirectory <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTP_HOST} ^(www.)?yoursite.com$ RewriteCond %{REQUEST_URI} !^/yoursubfolder/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /yoursubfolder/$1 RewriteCond %{HTTP_HOST} ^(www.)?yoursite.com$ RewriteRule ^(/)?$ yoursubfolder/index.php [L] </IfModule> With this approach we can protect root files and subdirectories from redirection. Are we done ? Yes and no. After these modifications pages are redirected correctly, but in the browser link you will note that subfolder's name is still showing. This is not good, we want to hide it. We are just one step away. Let's open our site/config.php and add the following line at the end: /** * Set urls root to hide Processwire folder * This must be combined with .htaccess in root directory */ $config->urls->root = '/'; Do not forget to lock site/config.php after modifying it. If you prefer, instead of modifying config.php, you can place the above line in _init.php. And here it is! I hope this simple tutorial can be of help.
  14. Hi @Mithlesh you should look at file site/templates/_main.php
  15. Hi @Mithlesh I gave a quick look to your site html source code, it seems social media icons are made using Font Awesome, by calling their classes 'fa-twitter' 'fa-facebook' 'fa-linkedin-square': If you wish to modify them you should work on the footer of your profile, changing the section above in site/templates/_main.php. If you need any further help please let me know.
  • Create New...