Jump to content

gebeer

Members
  • Posts

    1,489
  • Joined

  • Last visited

  • Days Won

    43

Everything posted by gebeer

  1. @adrian Just tried your code and compared time for both methods. Deletion of 3073 timestamps. using $editpage->ad_publish_at->removeAll(); 0.2848 seconds using foreach ($editpage->ad_publish_at as $t) { //ad_publish_at is my timestamps field $editpage->ad_publish_at->remove($t); } 0.7537 So removeAll() is significantly faster and speeds up my application. Thank you! Cheers Gerhard
  2. I implemented it so that the deletion of old timestamps happens only after the user submits the form and before the new timestamps get created and saved. For my scenario this is sufficient and I don't need other automation options. I'm just wondering whether there might be a faster method to delete timestamps other than my foreach loop in step #6 above (which is pretty fast already anyways ).
  3. I'm wondering, too if this could be automated. When I just add new timestamps, the old ones are still there. That's why I'm deleting them before I add new ones. Deleting takes around 1.6 seconds for 3000 timestamps. So I can live with that. But if there is a way to make this faster, I would be very interested.
  4. @kongondo My implementation is as follows. 1. installed the inputfield Timestamps module that you supplied. 2. created a field "ad_publish_at" of type timestamp and add it to my advertisement template 3. render the form on the frontend with code based on Soma's gist. 4. use a custom function to find recurrences from start and end dates in my advertisement template. The function uses the barely documented PHP DatePeriod class function getRecurrences($startTime,$endTime,$interval) { $format = 'Y-m-d H:i'; $start = new DateTime(); $end = new DateTime(); $start->setTimestamp($startTime); $end->setTimestamp($endTime); $end = $end->modify( '+1 minute' ); $duration = 'PT' . $interval . 'M'; //where $interval is 15, 30 or 60 $interval = new DateInterval($duration); $daterange = new DatePeriod($start, $interval ,$end); return $daterange; } 5. $daterange contains an array of DateTime objects. I loop through them, convert each into a timestamp and save that to my timestamps field $times = getRecurrences($startTime,$endTime,$interval); //this is the daterange array with DateTime objects foreach ($times as $t) { $t = $t->getTimestamp(); $timestamp = new Timestamp();//this is the Class Timestamp found in Timestamp.php. Included via FieldtypeTimestamps. $timestamp->date = $t; // note stored in column 'data' in the db of the Field $editpage->ad_publish_at->add($timestamp); } 6. when a user edits an advertisement and changes dates, I have to manually delete all previously saved timestamps, before I add the new ones with step 5 above. For deleting the "old" timestamps I use this foreach ($editpage->ad_publish_at as $t) { //ad_publish_at is my timestamps field $editpage->ad_publish_at->remove($t); } If you have any further questions on my implementation, please ask.
  5. I have the exact same scenario and am using page field like sforsman suggested. To make your filters work you can use URL segments. Works like a charm.
  6. $answers = $pw->community("answers=awesome"); foreach ($answers as $answer) { echo "Thank you " . $answer->createdUser->name . " "; } :)
  7. OK, this is solved now. The most efficient and performant method for storing multiple (even thousands) of timestamps with a page definitely is a custom input field type that stores values in an extra table in the DB which makes it really fast. Thanks to all who contributed, especially kongondo who was so kind to supply a customized input field Timestamps module derived from the input field events module. I can now save about 3000 timestamps for a page within 2 seconds which is really fast compared to other methods that I have tried. Also searching through those timestamps is pretty fast, even when it comes to hundreds of pages that need to be searched for a timestamp value. PW really is great tool and the detailed help and instructions here in the forum is absolutely awesome. I also learned a lot about PHP and the inner workings of PW during the process. Thanks again!
  8. @kongondo In my foreach, the values are converted to timestamps before I send them to the Timestamps module (note the 2nd line here) foreach ($times as $t) { $t = $t->getTimestamp(); $timestamp = new Timestamp();//this is the Class Timestamp found in Timestamp.php. Included via FieldtypeTimestamps. $timestamp->date = $t; // note stored in column 'data' in the db of the Field $editpage->ad_publish_at->add($timestamp); } That's why I don't understand that PHP Notice. But my solution to convert the value again with strtotime seems to be working fine and everything behaves as expected. So no need to worry about it any further.
  9. @horst I see what you mean. But in my code I already turn off output formatting. S I don't quite understand why a formatted value is being returned. $editpage->of(false); foreach($adform as $field) { if(in_array($field->name, $ignorefields)) continue; $editpage->set($field->name, $field->value); } $editpage->title = $editpageTitle->value; $editpage->name = "ad-".$sanitizer->pageName($editpage->title)."-".$uID; $deletetimer = Debug::timer(); //delete all old timestamps for that page before saving new ones $numberDeleted = iterator_count($editpage->ad_publish_at); foreach ($editpage->ad_publish_at as $t) { $editpage->ad_publish_at->remove($t); } $deletetimer = Debug::timer($deletetimer); $runtimer = Debug::timer(); $startTime = $adform->get("ad_publish_up")->value; $endTime = $adform->get("ad_publish_down")->value; $interval = $adFrequency->value->value; if ($interval == "0") { $numberCreated = 1; $timestamp = new Timestamp();//this is the Class Timestamp found in Timestamp.php. Included via FieldtypeTimestamps. $timestamp->date = $startTime; // note stored in column 'data' in the db of the Field $editpage->ad_publish_at->add($timestamp); } else { $times = getRecurrences($startTime,$endTime,$interval); $numberCreated = iterator_count($times); foreach ($times as $t) { $t = $t->getTimestamp(); $timestamp = new Timestamp();//this is the Class Timestamp found in Timestamp.php. Included via FieldtypeTimestamps. $timestamp->date = $t; // note stored in column 'data' in the db of the Field $editpage->ad_publish_at->add($timestamp); } } $runtimer = Debug::timer($runtimer); $editpage->save(); $editpage->of(true);
  10. I also found how to delete timestamps via the API here. In my case I do foreach ($editpage->ad_publish_at as $t) { $editpage->ad_publish_at->remove($t); }
  11. @horst thanks for pointing this out. In my foreach, I already convert $t to an integer with $t = $t->getTimestamp(); I did some research on the PHP Notice about the non well formed numeric value and found a question on stackoverflow. Following the proposed solution there, I altered line 32 in InputfieldTimestamps.module to read $date = $timestamp->date > 0 ? date(Timestamp::dateFormat, strtotime($timestamp->date)) : ''; Now the PHP Notice is gone And I get the correct dates shown
  12. I can't delete timestamps using the trash icons in my form. This might be related to this post (towards the end). I tried commenting out if("$timestamps" != "$this->value" || $numDeleted) { in InputfieldTimestamps.module. But still I can't delete or save changes through manual input in my form. Looking at the module code I can't seem to find a method for deleting entries. How would I go about deleting all entries for a specific page via API?
  13. I installed the module and added a field "ad_publish_at" of type Timestamp to my advertisement template. I also added logic for storing my timestamp values $times = getRecurrences($startTime,$endTime,$interval); foreach ($times as $t) { $t = $t->getTimestamp(); $timestamp = new Timestamp();//this is the Class Timestamp found in Timestamp.php. Included via FieldtypeTimestamps. $timestamp->date = $t; // note stored in column 'data' in the db of the Field $editpage->ad_publish_at->add($timestamp); } Timestamps get calculated correctly and are saved in their own DB table For debugging purposes I show the field in my frontend form. There I encounter a problem: same date is shown for all timestamps I get a PHP Notice Notice: A non well formed numeric value encountered in /var/www/gocinet/site/modules/FieldTypeTimestamps/InputfieldTimestamps.module on line 32 Line 32 in InputfieldTimestamps.module reads $date = $timestamp->date > 0 ? date(Timestamp::dateFormat, $timestamp->date) : '';//formatted date - Y-m-d H:i [see Timestamp.php] With var_dump($timestamp->date), I get string '2014-10-14 20:00' Even if I set different dateFormat like d/m/Y, Y-m-d, I always get that notice and all date inputs in the form show the same dates (Unix Epoch start). Any ideas what could cause this behaviour?
  14. Do you need this for a frontend form or in the admin? If you are building a frontend form via the API, you could try something like //get page for which to build the form $editpage = $pages->get("template=mytemplate, other selectors"); // just example selectors, they depend on your needs $parentID = $editpage->parentID; // create a new form field (also field wrapper) $form = $modules->get("InputfieldForm"); $form->action = "./"; $form->method = "post"; $form->attr("id+name",'myform'); // create field only if page parent_id=1032 if ($parentID == 1032) { $field = $modules->get("InputfieldText"); $field->label = "Label"; $field->attr("id+name","myfieldname"); $field->attr("value",$editpage->myfieldname); $form->append($field); } //...other fields If you could explain your use case in more detail, I'm sure we can find a solution that fits your needs.
  15. This week we have an event here in Nuremberg/Germany called Nürnberg Web Week. Last night was the "CMS Night" which is organized by the Joomla user group Nürnberg. In the email reminder for that event, they also mentioned ProcessWire as one topic. Also at other congresses in my area, PW is being promoted as a very flexible CMS/CMF solution. So we can hope for a bright future for PW.
  16. Awesome! Thank you so much kongondo. PW forum is really outstanding thanks to people like you I'll be on the road until the weekend but sure will find some time for implementing/testing this while I'm on the train. Will report back here how it works out. Cheers Gerhard
  17. The EventField module is very interesting. But, honestly, the code is going a little bit over my head. So I'm not quite sure how I would implement something similar for my use case. Especially I don't quite understand yet how the storing part works. Only DB related method I can find in the module code is getDatabaseSchema(); I'll try to describe as exactly as possible what I need. My form is frontend and populated from a template "advertisement". Relevant fields: -ad_publish_up: date field -> publishing start date/time -ad_publish_down: date field -> publishing end date/time -ad_frequency: radio (from pages) -> interval that advert should get published (0,15,30,60 min) -ad_publish_at: this would be my custom field type that stores all publishing dates as timestamps in an extra table. The form is working and the processing logic is implemented: -calculate recurrences from ad_publish_up, ad_publish_down and ad_frequency as timestamps -store those timestamps in ad_publish_at: ATM a textarea field, timestamps are stored comma delimited What I need now, is a custom field type that stores all timestamps for an advert in a table. There's only one column required in that table. Later I need to be able to search for adverts with a certain timestamp within my custom field with a query like $pages->find("template=advertisement, ad_publish_at=$timestamp"); I don't need all the input field logic because the timestamps will never get entered manually through the form. They will come from an array and each item in that array will be stored as one row in the custom field table. If you could give me any pointers on how to modify the EventField module so it will fit my needs, I'll be more than happy. Cheers Gerhard
  18. @sforsman + kongondo Thanks a lot for your suggestions. I'll have a look at Ryans Event Field type code and get back here if I have questions.
  19. Now I have searched through 500 ads to find timestamp within comma delimited values in a textarea field using this query: $ads = $pages->find("template=advertisement, ad_publish_at*=$ts"); 500 matches. Time: 0.7691 s As I will not have to search through more than 50-100 ads, I can live with the performance. So I will choose option 1 and save my timestamps as comma delimited values in a textarea field.
  20. Results for saving 581 timestamps: 1. save as comma delimited values in a textarea field: 0.0258 s 2. save each in a page (create and sve 581 pages): 18.1477 s So clearly, option 1 would be the way to go for saving timestamps. Next I will benchmark search times and add them to this post. Search results 1.Searching through 5 pages to find a timestamp inside a comma delimited list (about 600 timestamps) with this query. 5matches. $ads = $pages->find("template=advertisement, ad_server={$serverID}, ad_publish_at*=$ts"); 0.0264 s 2. Searching through 2600 pages to find the timestamp. with this query. 5 matches. $ads = $pages->find("template=publishing_schedule, publish_at=$ts"); 0.0200 s I will have to create some more ads to see how option 1 performs when more pages need to be searched. But ATM it looks like I will go with option 1 because it is significantly faster when saving timestamps.
  21. Thanks for the link to the debug class. I found two posts that show how to use the Debug::Timer() method here and here. Will use those examples in my code for benchmarking my searches and get back with results here.
  22. Update: My function for calculating the recurrences is working fine and producing the correct timestamps. I tried and compared both methods in terms of performance. When I save each timestamp in an extra page together with the advert id, as suggested by netcarver, it takes quite a long time to create and save those pages if I have hundreds of timestamps for one ad. If it gets beyond 1300 or so pages, I get an error Maximum execution time of 30 seconds exceeded I could set a higher limit for the execution time. But then the user would have to wait quite some time until the operation is finished. I need to delete all timestamp pages that belong to an ad when the ad gets edited and the start/end times change, before the new timestamp pages get created. This also takes quite long for 100s of pages. So I also tried option 1 from my first post and save all timestamps comma delimited in a textarea field. This is much much faster when creating/editing an ad. Now I have to benchmark and compare the 2 methods when it comes to searching through the timestamps either as pages or within the textarea. Is there a PW way of showing execution times when $config->debug = true? Couldn't find anything on showing debug info in the frontend except Ryan's post here.
  23. Seems like I'm working too many hours and can't think clearly ATM. Taken my function from above, I could easily calculate the count from it and use that in either when or recurr function getRecurrenceCount($start,$end,$interval) { $format = 'Y-m-d H:i'; $start = DateTime::createFromFormat($format, $start); $end = DateTime::createFromFormat($format, $end); $end = $end->modify( '+1 minute' ); $duration = 'PT' . $interval . 'M'; $interval = new DateInterval($duration); $daterange = new DatePeriod($start, $interval ,$end); $count = iterator_count($daterange); return $count; }
  24. As both, when and recurr do not work for start/end dates but rather need a count for recurring events, I don't really want to use them because I can't get my head around calculating the count from start and end date and my interval. For now I'm using my own function derived from here to calculate my recurring events. It is not really flexible and assumes that you provide the date/time in a specific format and the interval in minutes. This function suits my job and makes use of the PHP DatePeriod Class. function getRecurrences($start,$end,$interval) { $format = 'Y-m-d H:i'; $start = DateTime::createFromFormat($format, $start); $end = DateTime::createFromFormat($format, $end); $end = $end->modify( '+1 minute' ); $duration = 'PT' . $interval . 'M'; $interval = new DateInterval($duration); $daterange = new DatePeriod($start, $interval ,$end); return $daterange; /* to get the timstamps use a loop like this foreach($daterange as $date){ echo $date->format($format) . " : " . $date->getTimestamp() . "<br>"; }*/ }
×
×
  • Create New...