Jump to content

kongondo

PW-Moderators
  • Posts

    7,479
  • Joined

  • Last visited

  • Days Won

    146

Everything posted by kongondo

  1. What @AndZyk said. Below is one way to do it. Before that though, logic whether something exists should really be done server-side. Yes, you can also do client-side checks the way you are doing it (just for UX) as long as you also validate things server-side. Otherwise, if you only do it client-side, it is easy to change the 'valid until date' of the coupon in the markup and send that to the server which would honour the coupon and you'd incur a loss in your takings :-). I hope you are also checking server-side. OK, here's the code. It makes things cleaner, more readable and is less prone to mistakes since PHP handles the JSON string. <?php // initialise variables $couponsArray = array(); $couponsJSON = ''; // fetch coupons $coupons = $pages->find("template=paddiscount, title!='', pad_percentage!=''"); // we found coupons if($coupons->count) { // loop through coupons and add values to coupons array foreach($coupons as $coupon) { // if coupon valid until, get human readable valid until date, else empty $couponValidUntil = $coupon->pad_valid_until ? date("Y-m-d", $coupon->pad_valid_until) : ''; $couponsArray[$coupon->title] = $couponValidUntil; } // generate JSON string of coupons for JavaScript $couponsJSON = json_encode($couponsArray); } ?> <!-- html here --> <script type="text/javascript">var coupons = <?php echo $couponsJSON ?></script> Then in your JavaScript do your checks, if var coupons is not empty, etc. Hope this helps :-).
  2. Maybe I am not reading this correctly, but why do you need a Hook? The code is from the default site profile that ships with ProcessWire: <?php if($user->isLoggedin()) { // if user is logged in, show a logout link echo "<a href='{$config->urls->admin}login/logout/'>" . sprintf(__('Logout (%s)'), $user->name) . "</a>"; } else { // if user not logged in, show a login link echo "<a href='{$config->urls->admin}'>" . __('Admin Login') . "</a>"; } ?> Or maybe you mean you want them to login from a page other than the admin page?
  3. I'm using the core ProcessWire image field, so no. All, Anyone knows what's going on here?
  4. I've noticed that as well. I think that's weird. Maybe a bug or a cache issue in ProcessWire? I've not seen this behaviour before. I've been able to get rid of the 'blank references to deleted images' by deleting them in the page editor.
  5. Sorry again. Saturday night! My bad. Call this before delete $p->of(false); I edited my post above as well.
  6. Oops, my bad. You need to save the page as well. Do this after and outside the foreach. So $p->save() as shown below. <?php include('./_head.php'); // include header markup ?> <?php if($user->isSuperuser()) { $p = $pages->get(1029); // delete some images based on some condition foreach ($p->images as $img) { if($img->filesize<300000) continue;# if some condition met, skip deleting this image echo $img->name.'wird gelöscht<br>'; $p->images->delete($img); } // set page output formatting off first $p->of(false); // save page 1029 to effect changes $p->save(); // if deleting all #$p->images->deleteAll(); } ?> <?php include('./_foot.php'); // include footer markup ?> note: code edited
  7. Awesome! I really need to get some time to test it! This topic should be marked as [almost solved], eh? ;-). Read @bernhard tutorial on Process Modules and use his RockGrid module ?
  8. Here's something to chew on. Start with this tutorial: https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/ Some code to play with. This creates a paginated ProcessWire-rendered HTML table. Create a module as per above tutorial. Use the following code in your Process module's execute() method. You need to create some people pages. In this example, they use the template 'people'. Edit functionality not included. Have a look at Blog module for that, here. For CSV upload (not included), have a look at Matrix module here for uploading CSV file and here for reading CSV file. /** * Display, Add and Edit People. * * Called when the URL is peoples's page URL + "/people/" i.e. URL Segment. * Renders a table with People information. People can be edited via modal. * * @access protected * @return mixed $form rendered form * */ public function ___execute() { $modules = $this->wire('modules'); $input = $this->wire('input')->post; $pages = $this->wire('pages'); // CREATE A NEW FORM $form = $modules->get('InputfieldForm'); $form->attr('id', 'people'); $form->action = './'; $form->method = 'post'; // CREATE AN INPUTFIELD MARKUP: Will hold list of people table $m = $modules->get('InputfieldMarkup'); $m->textFormat = Inputfield::textFormatNone;// make sure ProcessWire renders custom HTML // $m->label = $this->_('Edit'); // $m->description = $this->_('Click on a title to edit the item.'); // CREATE A NEW TABLE: for people $t = $modules->get('MarkupAdminDataTable'); $t->setEncodeEntities(false); $t->setClass('peopleTable'); // set header rows $peopleTableHeaders = array( '<input type="checkbox" class="toggle_all">', $this->_('Title'), $this->_('Name'), $this->_('Surname'), $this->_('Another Column'), $this->_('One More Column'), $this->_('Published'), #$this->_('Date'), ); $t->headerRow($peopleTableHeaders); // grab a limited number of people to show in people dashboard. Limit is hardcoded in this example $people = $pages->find("template=people, include=all, sort=-created, parent!=7, limit=10"); foreach ($people as $p) { if (!count($people)) break;// if no people found, break early // check if person page is published or not $p->is(Page::statusUnpublished) ? $status = '<span class="unpublished">' . $this->_('No') . '</span>' : $status = $this->_('Yes'); // set table rows $peopleTable = array( "<input type='checkbox' name='posts_action[]' value='{$p->id}' class='toggle'>",// disabled sorting on this in .js file "<a href='{$this->wire('config')->urls->admin}page/edit/?id={$p->id}&modal=1' class='editPeople pw-modal pw-modal-medium'>$p->title</a>", $p->title, $p->person_name, $p->person_surname, $p->another_column, $p->one_more_column, $status ); // render the table rows with variables set above $t->row($peopleTable); }// end foreach $people as $p // display a headline indicating quantities. We'll add this to people dashboard $start = $people->getStart()+1; $end = $start + count($people)-1; $total = $people->getTotal(); if($total) $peopleCount = "<h4>" . sprintf(__('People %1$d to %2$d of %3$d'), $start, $end, $total) . "</h4>"; // add a description to people dashboard {postsCount, limitSelect and instruction OR no people found status} $m->description = $total == 0 ? $this->_('No items found.') : $peopleCount . $this->_('Click on a title to edit the item.'); $m->notes = "People table notes"; $currentUrl = $this->wire('page')->url . $this->wire('input')->urlSegmentsStr."/";// get the url segment string. In this case it is "people" $pagination = $people->renderPager(array('baseUrl' => $currentUrl)); $m->attr('value', $pagination . $t->render() . $pagination);// wrap our table with pagination $form->add($m); $post = $this->wire('input')->post; // render the final form return $form->render(); }
  9. Luke, the reason am asking particular questions is so that we can offer a tailored response. Without more information, it is difficult to offer a specific answer. For instance, I asked, how many columns in the database? But it seems to me you now want to go with pages, as per our suggestion, right? Assuming you are going with pages. Display Your process module, in its execute function (I am assuming you've read about this?) will render your HTML table. You can either render a ProcessWire table, or your own custom HTML table, or use Process Lister or RockGrid. All of this can be paginated so that only a limited number of people are loaded at a time. See Process Blog module for displaying pages in a HTML table. In the HTML table, do you want to display all data columns (e.g. name, surname, fiscal thingy, etc) OR do you want to display only full name (i.e. Steve Job?) Modal Then when client clicks on Steve Job, it opens a modal to the Steve Job page. The Steve Job page has several fields for name, surname, fiscal thing, etc. The client edits the fields he wants and closes the modal The page reloads (or if using ajax, only the data reloads) See Blog module (Process blog for opening pages in modal for editing) Note: Since the pages are in admin, we will have to by-pass user access check in order for client to edit the page Uploading new 'people' We have a button or file field for uploading new people data as CSV (see my FieldtypeMatrix module for example) When the csv file is uploaded, a script loops through it and creates people pages on the fly, mapping csv columns data to the ProcessWire page's fields. Before creating a page we check if there is already a people page with similar data {same email, same name, same surname, etc} You then decide what you need to do; update if duplicate found or skip creation of that people page? People page reloads (or ajax refresh) These are ideas, but very doable. But we need specific answers to our questions. You never know; someone might just create a draft module for you ?
  10. Yeah, what @flydev said. Pages is the easier route in your case. We are not saying it cannot be done by using your custom database and querying it directly. That's possible, but in your case, a lot more technical work. Your client does not have to see the tree of people pages. You can have those hidden under a single parent whose parent is /admin/ rather than home (/). This way, only superusers can see the people tree. With a Process Module, you don't have to be visiting the page tree even as a superuser. You only need to know that they are there and the evidence is that you can see them in your Process Module :-). The 'each person is a page' approach means that ProcessWire does all the heavy lifting, dealing with databases operations. Heck, your Process Module will allow you to filter users or sort them according to some column. Your database columns, depending on the data, can either be stored as single ProcessWire fields - name=text;surname=text,other_data=integer, etc OR as one blob of JSON text in a single text field, which can be retrieved and turned into an array. We need to see the column names and how many you got, to give a definite answer. How has your client been updating the database in the old website? You still haven't told us how soon you need this ?
  11. Is the client going to type in the data one by one or are you importing from a file, .e.g a CSV or JSON file? How many people potentially in the datasheet? Will this be done once or will the people be regularly updated? Can the people be saved as pages (hidden in admin) or you'd rather have them in a table external to ProcessWire? Manage People Datasheet You might need to create a simple Process Module, maybe even a one pager that lists the 'people'. You can include some simple actions like delete or edit people. To add people, a click on some button could open a modal window for you to add a person (depends on whether you are importing a file of people or typing manually). There's also the module RockGrid that you can use for listing the 'people'. I don't know if it can do data imports though. I think it works with ProcessWire pages only, but am not sure. User registration Since creating users is a manual process, you have a lot of control here. How you check if a user is on the allowed people list depends on the approach you take above, i.e. whether people are pages or are in a custom database. If they are pages, you can use $pages API, e.g. $newUser = $pages->get("template=people, first_name=$firstName,last_name=$lastName"); Then check if that returned something. If yes, register this user. If you are using a custom table, you'd need to use SQL to fetch, insert, update, etc, people. ProcessWire has a $database API that you can use Your other option is a custom Fieldtype but that is a bit more technical, going by how you've described your current skill set. Depending on your timescales, you might be able to get some help in the forums. If this is needed fairly soon, you might want to consider hiring an experienced ProcessWire developer to carry out the work for you.
  12. Thanks @adrian. I was looking for that one but couldn't find it. I had a feeling I'd read about it somewhere. How would it work in this case, just throw in the page ref field in the selector part?
  13. $faqs = $pages->find("template=template-of-faq-pages, page_ref_field_of_faqs=$page, limit=10"); we are limiting to 10 hits in this example.
  14. Use the API :-). Log in as a super user and throw the following code in some template file and visit a page that uses that template. Delete the code from the template file when done. if($user->isSuperuser()) { $p = $pages->get(1029); // delete some images based on some condition foreach ($p->images as $img) { if($someCondition) continue;# if some condition met, skip deleting this image $p->images->delete($img); } // if deleting all #$p->images->deleteAll(); } Alternatively, use the API to create thumbs in the size ProcessWire would have generated.
  15. ?. Yeah. What @adrian said. PHP is most likely running out of memory when ProcessWire tries to create thumbs for those images. Second time round, they should load fine (assuming the thumbs creation finished). Maybe also see if you need to rethink your approach? 300 images on one page, from a UX point of view can be 'not-so-friendly'?
  16. Hmm. More Intelephense quirks. This extension just doesn't want to work on my system. If I hover over a variable, I expect it to show me (peek preview) the value of that variable as initially set. It doesn't do this. At times it shows the variable type at times it shows nothing. With PHP IntelliSense, it works every time. I get these on hover.
  17. What tool is that, btw?
  18. Hi @derelektrischemoench, This code: $targetPage = $pages->get($menuItem->id); is the problem. For objects returned by getMenuItems(), id refers to the internal menu item ID in the collection AND NOT the corresponding ProcessWire page ID :-). Apologies, documentation could be clearer. To get the ProcessWire page ID of that menu item, use pagesID instead. So: $targetPage = $pages->get($menuItem->pagesID); By the way, please note that menu items with a pagesID of 0 are external menu items (e.g. an item pointing to google.com, etc). And while we are here.. This: $targetPage->get('images'); Could be changed to: $targetPage->images; However, your code shows that you are returning the whole 'images' field object. That is why you see this: ["pictures"]=> object(ProcessWire\Pageimages)#235 (2) { ["count"]=> int(1) ["items"]=> array(1) { ["steinlampe_2_grayscale.png"]=> string(26) "steinlampe_2_grayscale.png" Is that intentional? Aren't you really after the url of the image? Secondly, how many images are in each menu item's images field? Is the image field a multi image field or single? If multi, you need to loop through it if you want multiple images from it, or get the first one using first(). If it is a single image field, you are fine, you can just grab the URL.
  19. Or remove them. You don't need them in this case ?
  20. Haven't looked at the inner workings of this yet, but is this something (caching) that Wire Cache could do?
  21. I have updated the original snippet (variables API) in the Gist. This addresses the > issue reported by @adrian. Typing doesn't change. E.g.g pagesfind vs pages find will return the same suggestion.
  22. Facepalm! ?. I was testing in a workspace where wire folder was not part of the workspace!!! Thanks guys. It works. After further testing, I think I'll stick with my snippets though due to the following reasons: Intelephense requires that I type the -> i.e.. First, I type pages, then I type ->, then I select the property/method I want. Meaning, to get $pages->find('selector'), I need to type 3 times! And it doesn't give me the "" around the string 'selector'. Using the snippets, I only need to type once; e.g., pagesfind, hit tab and bam, I get the whole thing, $pages->find("selector"); With the snippets, I get the closing semicolon at the end of the statement. Not with intelephense With the snippets, I can use normal variable syntax; I don't use the Functions API ? Aah. This is because I had Auto Close Tag before support was included in VSC 1.16. Also, one has to enable it on editor.quickSuggestions > strings:true :-).
  23. Great! Oh no! That's because it is matching the > in the prefix value in the snippet. So, I should change this: "prefix": "pages->find(\"selector\")" to this: "prefix": "pagesfind(\"selector\")" Thanks for catching this, but hey, you shouldn't be typing HTML closing tags! ? VSC extensions should do that for you. See Auto Close Tag. It can do this: Have a look at Auto Rename Tag as well (it acts up sometimes though). Regarding ProcessWire variables, first check out intelephense (as per previous discussions earlier today). If it works for you, then no need for my snippets :-). I've gone back to my snippets atm since intelephense is not working for me ?
×
×
  • Create New...