-
Posts
372 -
Joined
Everything posted by hellomoto
-
Actually I don't think repeaters really can be set in importPageValue, because the column header isn't passed to it. So it would be better to set them as options in build form 2 (and more direct).
-
I installed ServiceCurrencyConversion and it's great. I was wondering if any of you by chance had any experience with using this as I would expect it would often be used, to search by price... in your currency. Right now I have products that each have fields price_currency and price_amount. So each has a native currency. I am able to show the price in each currency we currently support on our listings index by way of this function: function currencyConvert($page) { //echo $page->id . '<br/>'; $cc = wire('modules')->get('ServiceCurrencyConversion'); $current = $page->price_currency->name; $amt = $page->price_amount; $currencies = wire("pages")->find('parent=1135,include=all'); //echo count($currencies) . '<br/>'; $converted = []; foreach($currencies as $currency) { //echo $currency->name; //if($currency = $cc) continue; //$converted["$currency->name"] = $cc->convert($current, $currency->name, $page->price_amount); //if($current != $currency->name) { //echo " Set: $current Now: $currency->name Amt: $page->price_amount "; $converted[$currency->name] = $cc->convert(strToUpper($current), strToUpper($currency->name), $page->price_amount); $amount = $currency->name == 'eur' ? number_format($converted[$currency->name], 0, ',', ' ') : number_format($converted[$currency->name]); $converted[$currency->name] = wire("pages")->find("parent=1135, name=$currency->name, include=all")->first()->title . $amount; //} } //print_r($converted); return $converted; //echo '<br/><br/>'; } So in my listings index I have: foreach(wire("pages")->find('parent=1135, include=all') as $currency) { if($currency->name != $item->price_currency->name) $price .= ' / ' . currencyConvert($item)[$currency->name]; } That outputs the price in every currency that isn't the default for the listing (which is already output). So I already have a search in place for listings that searches by the price_amount. I want to incorporate the different currencies in my search, while not excluding results based on their set currency. The way I have this set up currently works, but incorrectly, as it doesn't restrict listings based on their currency conversion. Now that I can convert them I want to fix the search feature to accommodate this. So how can I do this? I would think to maybe store a separate price_amount per currency, with a default set (to base other values from), but this does seem a bit tricky... Right now only 3 currencies are supported but if it grows to be a large amount it might become unwieldy. If that's the right way to do it though, so I will. Or, just leave the fields as-is, and go by the chosen currency in the search, returning all results that match the amount in that currency. This is what I would like to do because it seems simpler. But then I worry about performance... This means every search would have to convert the price for potentially almost every listing, and that's before even returning a set of results!(?) Like, you would have to search, with a currency and max. and/or min. amount set for price... then that search would have to first process the converted price for every listing that fits all the other search criteria, right (potentially all), and then return the values that match the price range in the chosen currency. That sounds like too much to me. Also obviously outputting the price in every currency we have would get too lengthy so I want to be able to target a single one efficiently. You see my dilemma? Anyone more knowledgeable have any advice, please? Much appreciated.
-
Well this seems to work ok: protected function setPriceHistory($event) { $page = $event->arguments('page'); if($page->template != 'vessel') return; if($page->price_amount) { if(!$page->price_amount_hold) { $page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save(); $this->message("Updated hold price to current price."); } elseif($page->price_amount_hold && $page->price_amount != $page->price_amount_hold && !$page->is('unpublished')) { if($page->price_amount < $page->price_amount_hold) { $page->set("price_amount_was", $page->price_amount_hold)->set("price_cut_date", wireDate('Y-m-d')); $this->message("Price Cut set on " . wireDate('Y-m-d', $page->price_cut_date) . "."); } $page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n"); $pos = strpos($page->price_history, "\n", 1600); // Search for linebreaks after 1600 chars if($pos) $page->price_history = substr($page->price_history, 0, $pos); // Limit the string $page->save(); $this->message("Updated price history."); } } if($page->price_cut_clear) { $page->set("price_cut_date", "")->set("price_cut_clear", false)->save(); $this->message("Price cut cleared."); } }
-
Okay so this was working, but now it seems to time out since I added changed the second condition to != and put the < within that: protected function setPriceHistory($event) { $page = $event->arguments('page'); if($page->template != 'vessel') return; if($page->price_amount) { //$this->message("Price exists"); if(!$page->price_amount_hold) { $page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save(); // append price_amount, date(), newline to price_history $this->message("Updated hold price to current price."); } if($page->price_amount != $page->price_amount_hold && !$page->is('unpublished')) { if($page->price_amount < $page->price_amount_hold) { $page->set("price_amount_was", $page->price_amount_hold)->save(); $this->message("Price Cut set on {$page->price_cut_date}."); } $page->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save(); $this->message("Updated price history."); } //$page->save(); } } See it was working up until I tried adding price history for any change in price, as opposed to only when it's cut. I thought it might be too many page->saves at once, so I removed the last save() from each of the changes, and just put it at the bottom... Still doesn't work, I get no data received, or a timeout: Oh. and it added about a million of the same line from the same save, that's why it timed out... Why might that be..?
-
Teppo got me to realize that I can simply do $page->$field->address = $value. So now map marker address can be imported which means it's time to tackle the repeaters... oy.
-
Ah yes it works! Thank you I didn't even know you could string variables like that!
-
I know repeaters are pages... For my main template that I am trying to get this to work for primarily, I have a repeater field engines with the default ready set to 2. So I would assume that these are created nonetheless when creating a page of that template via the API... This is tricky. I think perhaps the individual repeater fields should be included in the fields list when matching them prior to actually importing and then separate the values into repeaters on import? Anyway I think I'll try to get the mapmarker working first. The $value in importPageValue isn't what's returned by MapMarker, it's the value you're setting for the field, from the CSV.
-
My vessel template has a price field (actually field group: with price_currency, price_amount). But when the price is lowered, the listing should qualify to appear on a "Price Cuts" page automatically... so here's what I'm doing (or skip to the bottom): So I was thinking I could add another couple of read-only fields, price_amount_was (since it's unlikely that the currency would change) and price_cut_date. price_amount_was would default to the set price once one is set on save (starts empty, stays empty until a price is set and the page saved). price_cut_date would be null by default. Then another hook after page save would check if the price_amount is lower than price_amount_was, and if so, change the price_cut_date to the current day. Then my Price Cuts page could just show "template=vessel, limit=10, price_cut_date!='', sort=-price_cut_date". But if I wanted to keep a history of price cuts for each listing, that wouldn't work. I could use a repeater field but I don't think that's all that necessary, since only the current and last price (or I guess that'd be second-to-last, last is current) need be queryable. I could add another read-only textarea field, price_history, and on every save that the price is changed, append the price and date (comma-separated, followed by a newline). So that's what I'm trying to do now, but I don't know how to append to price_history. In my module init I hook after page save, this function: protected function setPriceHistory($event) { $page = $event->arguments('page'); if($page->template != 'vessel') return; if($page->price_amount) { //$this->message("Price exists"); if(!$page->price_amount_hold) { $page->set("price_amount_hold", $page->price_amount)->save(); // append price_amount, date(), newline to price_history $this->message("Updated hold price to current price."); } if($page->price_amount < $page->price_amount_hold) { $page->set("price_amount_was", $page->price_amount_hold)->set("price_amount_hold", $page->price_amount)->set("price_cut_date", wireDate('Y-m-d'))->save(); $this->message("Price Cut set on {$page->price_cut_date}."); } } } So you see that commented out line in if(!$page->price_amount_was){}... I could set the value, but I don't want to reset it, just add to it. Thanks.
-
$config->userTemplateIDs -- anyone implemented this so far?
hellomoto replied to hellomoto's topic in API & Templates
Thanks Lost. Good to know that that module keeps the originals too (and can back up the db), I don't see any reason not to use it next time. I was probably too fried from having tried doing that same tedious process a few times over already and messed something up... I got the site back by the way I feel like I must have mentioned it probably elsewhere, me with my multiple threads on the same topic... I just had to restore a db backup from 6 days prior instead of the site profile I had just created that day. No big deal, it's back up to date now. -
Simple WireMail implementation on localhost..?
hellomoto replied to hellomoto's topic in General Support
Oh so then the SMTP plugins are separate of PHP mail? Sounds good! But if that's the case, and my settings are supposed to be set up correctly in WireMailSmtp, why won't my email test work? -
What template file? I have rss.php in my templates directory. How is the feed accessed? I need to make a blank RSS template in PW? Never mind that worked
-
$config->userTemplateIDs -- anyone implemented this so far?
hellomoto replied to hellomoto's topic in API & Templates
And now... in a new PW master unzipped dir, I add my site-profile alongside all the others in its root, but it doesn't show up in the Installation Profiles select. Anything I might be able to do to get it to show up..? Yeah I undid my changes since they didn't work, I didn't want to just leave bogus settings =\ I should probably just hold off on these advanced user configurations. Now I just want my site back. -
$config->userTemplateIDs -- anyone implemented this so far?
hellomoto replied to hellomoto's topic in API & Templates
... Actually... now I can't log even log in, since trying to create a new user (got an error right when I clicked to add one); I get the below error, trying to access the front- or back-end. I exported my site profile just before upgrading though, so I'm not really worried... I have the original/stable wire dir and index.php too but I don't think restoring those will help much. Catchable fatal error: Argument 1 passed to Users::setCurrentUser() must be an instance of User, instance of Page given, called in /wire/core/Session.php on line 76 and defined in /wire/core/Users.php on line 39 Recoverable Fatal Error: Argument 1 passed to Users::setCurrentUser() must be an instance of User, instance of Page given, called in /wire/core/Session.php on line 76 and defined (line 39 of /wire/core/Users.php) This error message was shown because site is in debug mode ($config->debug = true; in /site/config.php). Error has been logged. Ah, gotcha. Thanks Lost. -
$config->userTemplateIDs -- anyone implemented this so far?
hellomoto replied to hellomoto's topic in API & Templates
Thanks Cstevensjr. & Sorry, Lost. I'm running around like a chicken without a head forgetting all my other threads... I'll be sure to check the ones I got going before posting any new topics from now on. So 2.5.14... that's a 14, not like .14, huh? So that it's greater than 3? Now I get it. Thanks a lot guys. I have upgraded to dev Now I should have success. -
Users -- visibility (need public) & hierarchy?
hellomoto replied to hellomoto's topic in General Support
Oh! Sorry Cstevens, hadn't seen that yet, thanks.- 6 replies
-
- users
- visibility
-
(and 1 more)
Tagged with:
-
Simple WireMail implementation on localhost..?
hellomoto replied to hellomoto's topic in General Support
Well I have WireMailSmtp enabled and it says my settings appear to work correctly... so now I'm testing my php mail. Do my WireMailSmtp SMTP settings need to match my server/php settings? -
Or the repeater subfields could be added to the select list for the field connections directly... that would simplify the importPageValue part. But still... if I do /** * Build the "Step 2" form to connect the fields * */ protected function buildForm2() { $form = $this->modules->get("InputfieldForm"); $form->method = 'post'; $form->action = './'; $form->description = "Step 2: Connect the fields"; $form->value = "Below is a list of fields found in your CSV file. " . "For each of them, select the field it should import to. " . "Leave any fields you want to exclude blank. " . "Once finished, click 'Start Import' at the bottom of this page. " . "Note: any field names in your CSV file that match those in your site " . "will be automatically selected."; $fp = fopen($this->csvFilename, "r"); $data = fgetcsv($fp, 0, $this->session->csvDelimeter, $this->session->csvEnclosure); foreach($data as $key => $value) { $f = $this->modules->get("InputfieldSelect"); $f->name = "csv" . $key; $f->label = $value; $f->addOption(''); foreach($this->template->fieldgroup as $field) { $valid = false; foreach($this->fieldtypes as $ft) { if($field->type instanceof $ft) { $valid = true; break; } } if(!$valid) continue; if($field->type instanceof FieldtypeRepeater) { echo count($field->repeaterFields); foreach($field->repeaterFields as $item) { echo wire("fields")->get($item)->name . '<br/>'; //$label = wire("fields")->get($item); //$label = $item->name; //$f->addOption($item->name); } } $label = $field->name; $f->addOption($field->name, $label); if($field->name == $value) $f->attr('value', $field->name); } $form->add($f); } fclose($fp); $this->addSubmit($form, 'Start Import'); return $form; } That returns 8 for count($field->repeaterFields), which is correct. Yet, executing the next foreach statement echoes 23 iterations of name of each subfield. For example: repeater field = "engines", its repeaterFields = ["engine_field1", "engine_field2", "engine_field3", "engine_field4", "engine_field5", "engine_field6", "engine_field7", "engine_field8"] and each of those are echoed out together -- 23x. Should just be once, for a total of 8 lines, not 184...
-
Resources (Ryan's own): ImportPagesCSV FieldtypeMapMarker So I edit the accepted $fieldtypes on :76: /** * List of Fieldtypes that we support importing to * */ protected $fieldtypes = array( 'FieldtypePageTitle', 'FieldtypeText', 'FieldtypeTextarea', 'FieldtypeInteger', 'FieldtypeFloat', 'FieldtypeEmail', 'FieldtypeURL', 'FieldtypeCheckbox', 'FieldtypeFile', 'FieldtypePage', 'FieldtypeMapMarker', 'FieldtypePassword', 'FieldtypeRepeater' ); Page, MapMarker, Password and Repeater were added by me. Then alter importPageValue: /** * Assign a value to a page field * */ protected function importPageValue(Page $page, $name, $value) { $field = $this->fields->get($name); if($field->type instanceof FieldtypeFile) { $value = trim($value); // split delimeted data to an array $value = preg_split('/[\r\n\t|]+/', $value); if($field->maxFiles == 1) $value = array_shift($value); $data = $page->ImportPagesCSVData; $data[$name] = $value; $page->ImportPagesCSVData = $data; } elseif($field->type instanceof FieldtypePage) { $value = trim($value); if(wire("pages")->find("$name=$value")) $page->set($name, $value); } elseif($field->type instanceof FieldtypeMapMarker) { $value = trim($value); $page->set($name->address, $value); } elseif($field->type instanceof FieldtypeRepeater) { // } else { $page->set($name, $value); if($name == 'title') $page->name = $this->sanitizer->pageName($value, 2); // Sanitizer::translate elseif($name == 'fullname') { $page->name = $this->sanitizer->pageName($value, true); } } } Page import works with ID values, which was trivial to incorporate; passwords too. MapMarker and Repeater as you might guess do not. How can I save the map->address value? Hopefully it will update the corresponding map fields too but one thing at a time. As for the repeaters... LostKobrakai tipped me off to foreach($page->engines as $e) { foreach($e->fields as $field) { echo $field; echo $e->get($field); } } which works for their names and values, but in this function you're passed the field, and something like foreach($page->$field as $e) { foreach($e->fields as $field) { echo $field; echo $e->get($field); } } doesn't work... and what it would need to do inside anyway is check for a subfield whose name is equal to the column header (choose the repeater field itself e.g., engines in the select per repeater subfield value, e.g., engine_fueltype), then explode that cell value by pipes ('|'), and for each subvalue, populate the repeater#->subvalue... but before all that I need to be able to iterate through the subfields from the field in this function. Anyone have any ideas?
-
I'm working with a PW 2.5.3 install. Here http://processwire.com/blog/posts/processwire-core-updates-2.5.14/ there is a quick tutorial on setting up an alternate user template and parent. I followed it to the T, but it didn't work; when adding a new user, there was no choice of template, and once the user was created the alternate template I had set wasn't even among the select options. Has anyone managed to do this or even just an alternate template successfully? The alt. tpl. is what I rly. need... I just tried it twice over and then erased and undid everything 2x too, so... Then I only unchecked "Don't allow pages to change their template?", cloned user template (id=75), added "$config->userTemplateIDs = array(3, 75);" to config.php created a new user No alternate template option still. This should be able to work right? Because I don't see a date for that blog post but do only see comments from 5 days ago, but it says 2.5.13, I'm using 2.5.3.
-
Users -- visibility (need public) & hierarchy?
hellomoto replied to hellomoto's topic in General Support
I follow the instructions exactly and when I add a new user, there's only the name field, not template, and once I enter a name and create, go to Settings tab, the one I have set for the alternate user tpl doesn't appear in the list. What a shame.- 6 replies
-
- users
- visibility
-
(and 1 more)
Tagged with:
-
Users -- visibility (need public) & hierarchy?
hellomoto replied to hellomoto's topic in General Support
Of course! I have to use include=all for other things already (like field options for public pages, which themselves are hidden)... man. Thank you. Okay, so that I did and it works as expected. However, since posting this thread I did go ahead and try the alternate user template/parent example given in that blog post I linked, and followed every step... but it didn't work. I try, try again.- 6 replies
-
- users
- visibility
-
(and 1 more)
Tagged with:
-
MatthewSchenker: I like DynaTable.
-
How to iterate through repeater fields' subfields?
hellomoto replied to hellomoto's topic in General Support
Thank you- 2 replies
-
- FieldtypeRepeater
- iterate
-
(and 1 more)
Tagged with: