Jump to content


  • Posts

  • Joined

  • Last visited

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

1,981 profile views

nickie's Achievements

Jr. Member

Jr. Member (3/6)




Community Answers

  1. In functions, use wire('user')->languageor, in case of module files: $this->wire('user')->language
  2. I would use some JS code that would add "placeholder" content to the inputfield elements (which would be easy, since they are all referenced by ID in the admin template) wherever I want default content. This way it would only be displayed if the field were empty, and shouldn't be particularly problematic from a security point of view either (I think...). Let me know if you want to see some example code.
  3. Thanks for the suggestion and the link, Pete, so far our front-end search needs were limited to the title field, but this is going to change soon as lots of social features are being implemented, so I will definitely need to learn all about the cache fieldtype. enricob, the site is currently in open beta and lacking some functionality and server tuning we want to have in place before sharing (especially as an example of what PW can do). A lot of new features are still being implemented and hopefully the site should be well-tested and ready to showcase within about a month. I am eagerly looking forward to posting a case-study about it in the forums then, and will drop you a note as a heads up.
  4. Hey there, I don't know which Admin theme you are using, but I think both Default and AdminThemeReno use the "ProcessPageList" module (in /wire/modules/Process/) to render the page tree on the "/admin/page" link. I checked the module settings and it doesn't have an option to select "show all subpages" (for good reason - there can be a lot of nesting or just a lot of children, which could slow down the render considerably or fail altogether), so some customization might be required in your case. I really like to root around in the module files, and found that in this module's "ProcessPageList.module" file an AJAX request is constructed to render the list, and the request includes which rootID to build the tree on (in this case it would be the homepage, so ID=1) and also includes whether/which IDs should be "open" - same as if you navigated to "/admin/page/?open=282" and it would show the whole page tree with all the parents of page ID 282 open and all its children visible. In the ProcessPageList.module file, this render function (in dev version) starts on #L117. You can see that the $openPageIDs array is defined from L122 to #L128: $openPageIDs = array(); if($this->openPage->id > 1) { $openPageIDs[] = $this->openPage->id; foreach($this->openPage->parents() as $parent) { if($parent->id > 1) $openPageIDs[] = $parent->id; } } (I'll assume a little familiarity with OO PHP, but if not there is no better place (IMHO) to learn that the module files.)As you can see above (and in the lines just following the above snippet), the openPagesID parameter in the initial request constructed in the .module file is an array, so we can actually just put in it all the children of the root page which have children, and it will execute the "open" request on each of those pages one-by-one. I tested the following solutions in AdminThemeReno (with PW 2.5.21 dev version) and it worked to open all the sub-page views one after another, so that in a couple of seconds you have the whole tree (subpages included) rendered. You can try out the one which works for your situation (and revert right back to the original in case of errors): Option 1: If you know that the nesting on your tree is only one level deep, it's pretty easy: $openPageIDs = array(); /**snippet to add:**/ // $this->openPage->id is a variable of the class instance indicated in the URL as ?open=IDnumber ($input->get->open's value), if it doesn't exist we use the root : foreach($this->pages->get($this->openPage->id ? $this->openPage->id : 1)->children as $child){ if($child->numChildren()) //if it has children, add it to the array of IDs to open: $openPageIDs[] = $child->id; } /**end snippet**/ if($this->openPage->id > 1) { $openPageIDs[] = $this->openPage->id; foreach($this->openPage->parents() as $parent) { if($parent->id > 1) $openPageIDs[] = $parent->id; } } The above might be enough for your case, especially if you have only one level deep nesting (only children of homepage have subchildren).Option 2: If you have a bit more nesting, here's a solution that works. Please beware that I'm not very good at OO PHP myself, and with a lot of children this might be pretty slow. Also, it uses a recursive function, and your PHP extensions might have a limit on how many nested calls are allowed (e.g xdebug allows 100 levels). Step 1. declare a protected variable for the whole class called $openAll (you can add it just after L26). Step 2. create a protected method for the class called getChildParents (or something less confusing): protected function getChildParents($id){ // pass the function ID of root/parent on which to check $p = $this->pages->get($id); foreach($p->children as $child){ if($child->numChildren()){ // if child has children, add it to the global variable $openAll: $this->openAll[] = $child->id; // call this function with child ID as parent ID: $this->getChildParents($child->id); } } } Step 3. Change the snippet I added in the first solution to the following: $openPageIDs = array(); /**snippet to add:**/ // instantiate the global variable as an empty array: $this->openAll = array(); // call the recursive function starting with the $input->get->open ID which will populate the array we just instantiated: $this->getChildParents($this->openPage->id ? $this->openPage->id : 1); // since openPageIDs array was empty to begin with, we can just copy our new array into it: if(count($this->openAll)) $openPageIDs = $this->openAll; /**end snippet **/ if($this->openPage->id > 1) { $openPageIDs[] = $this->openPage->id; foreach($this->openPage->parents() as $parent) { if($parent->id > 1) $openPageIDs[] = $parent->id; } } If any particular ID has a LOT of children but no subchildren, you can include a condition in the function to skip its checking.Option 3: Easiest option of all - if your client won't be creating new subnesting herself (adding children where none existed before), and if you already know which pages you want to open, you can skip all of the above and just instantiate $openPageIDs array to have a list of IDs you always want to open along with the homepage. In any case, it might take a second or two to have all of them render, so tell her to be patient. (PS: It's very possible there's an easier / less recursive way to do this in PW, in which case hopefully one of the experienced people will chime in and correct my method.) ETA: I changed the count selector to the built-in numChildren to check for children, which includes hidden children. You can also add the "include=all" condition on any of the ->children() or ->child() calls, especially if you are not seeing hidden/unpublished children where you want to see them. I do want to re-emphasize that this can become a memory intensive operation if applied to a site with many thousands of pages or many sublevels, but hope it helps in your case.
  5. I am currently managing a PW site with 2 million+ pages. It's admirably fast, and much, much faster than any other CMS we tested. Searching is also ridiculously fast when done on single fields like title. (I also just did a test search using the page finder and it took < 4 seconds to find pages which had a particular field empty from a template which has 1.63 million pages.) The site doesn't deal with many image or file uploads (yet), but two optimizations I have applied so far are to 1) always, always use limits on using $pages->find(), and 2)to cache the sitemaps (which contain thousands of links each) using Procache(https://processwire.com/api/modules/procache/) Once you know where specifically your site is using the most resources, you can apply more selective caching / database optimizations. Thanks for starting this topic, I learned about pageFileExtendedPaths... there's always some cool feature I didn't know about and now must have!
  6. Hey there, First, I think the field is "roles" not "role" - at least that's what my lister tells me (you can see the lister selector when debug mode is on)... anyway I don't think that's your main problem. I followed the exact same steps you did and the same thing happened to me - after I set a condition in inputfield dependency ("roles=38") for admin_theme field, which didn't work to hide the field - I removed the condition, and after that the field is not showing its options. So then I created two test fields (one integer and one Pagefield with radio selection for single Page only) and added it to user, then I followed the exact same steps (show only if "roles=38") - and it worked perfectly for both of them. Both fields show up in the edit-page of the users with role=38(superuser role in my case), but not in any of the others. So I'm thinking this may be a quirk of the admin_theme field. Ryan will probably take a look at it when he sees this, or you can post to github to get his attention if it's urgent.
  7. I have seen that error when fieldtype doesn't match input or a required field is empty, but it generally informs me what field was the problem (with a big old red notice on top of the field too). So that's weird that you're not getting any description of the problem. If you haven't added any of your own fields to the user template and have checked/double-checked the input of every form, here is what I would do : 1. turn on debug in /site/config.php and see if it gives any extra information 2. If that fails, search the code to see where it outputs that error. (Only one place: https://github.com/ryancramerdesign/ProcessWire/blob/676458407bd530b69b50c6ef2f44cf16e4ef4449/wire/modules/Process/ProcessPageEdit/ProcessPageEdit.module#L211) Based on that it's safe to assume you have some formErrors. Look a few lines before that (L195), I would temporarily change $formErrors = 0; foreach($this->notices as $notice) { if($notice instanceof NoticeError) $formErrors++; }to $formErrors = 0; foreach($this->notices as $notice) { if($notice instanceof NoticeError) { $this->error('Notice: '.$notice); $formErrors++; } } That might give you a clue about the notice that is causing a formError. Once you get that info (or even if you don't), you should undo the changes you made to the module file. Anyway it's a hack, but it's how I sometimes investigate what is happening...
  8. pages_id is not a column in pages, I think you are looking for 'id'. Results for query('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='pages'): +-------------------+ | COLUMN_NAME | +-------------------+ | id | | parent_id | | templates_id | | name | | status | | modified | | modified_users_id | | created | | created_users_id | | sort | +-------------------+
  9. Ryan, thanks for pointing me in the exact direction I needed to go! The PW version was not the issue, as I was using 2.5.21 dev. The file you linked to (Fields.php) was the exact source of the memory exhaustion, specifically on a line (caught in the trace too) inside the slow method: if($numPages <= 200 || $hasDeletePageField) { // not many pages to operate on, OR fieldtype has a custom deletePageField method, // so use verbose/slow method to delete the field from pages $items = $this->wire('pages')->find($selector); // << the problematic line, since I have 2.3million pages! //iterate through items etc } The test for the slower method was proving true because of $numPages, which is defined as $numPages = $this->getNumPages($field, array('template' => $template)); which calculates the number of pages which has the field set. So since the field was empty in all pages, numpages was turning out to be zero.I set the slow delete condition to 'false' temporarily, and was able to delete the field via admin in a heartbeat. Since the actual process of page-by-page field deletion doesn't make use of numPages at all, I'm thinking maybe it should be changed to include all pages of the template? Unless I'm missing some other use for it. In any case, thank you so much for the reply, sorted me right out.
  10. Thanks for the SQL code, Marc. And your warning is well heeded - backup and Xdebug are in order. I haven't run into the error in other places yet, but you are right, it's foolish to wait for that to happen before I deal with it.
  11. For relative URL, you can use: <a href="<?php echo $pages->get(23)->url;?>">Page with ID 23</a>If you want the full http URL, use ->httpUrl instead of ->url. Edited to add: Sorry, forgot to add the 's' to $pages - totally different variable
  12. Just wanted to add that deleting the field via admin (with debug on) results in the same issue and similar stack trace. I submit at a URL like /admin/setup/template/removeFields?id=50&fields=119 (confirm delete and submit page) and then get stuck at /admin/setup/template/removeFields which shows the following: Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 72 bytes) in www/wire/core/PageFinder.php on line 307 Call Stack: 0.0000 249512 1. {main}() www/index.php:0 0.0708 4524720 2. ProcessPageView->execute() www/index.php:240 0.0708 4525072 3. Wire->__call() www/index.php:240 0.0708 4525072 4. Wire->runHooks() www/wire/core/Wire.php:320 0.0708 4527200 5. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.0708 4527536 6. ProcessPageView->___execute() www/wire/core/Wire.php:365 0.0841 4898216 7. Page->render() www/wire/modules/Process/ProcessPageView.module:172 0.0841 4898400 8. Wire->__call() www/wire/modules/Process/ProcessPageView.module:172 0.0841 4898400 9. Wire->runHooks() www/wire/core/Wire.php:320 0.0842 4903392 10. PageRender->renderPage() www/wire/core/Wire.php:387 0.0842 4903744 11. Wire->__call() www/wire/core/Wire.php:387 0.0842 4903744 12. Wire->runHooks() www/wire/core/Wire.php:320 0.0842 4905872 13. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.0842 4906208 14. PageRender->___renderPage() www/wire/core/Wire.php:365 0.0846 4947200 15. TemplateFile->render() www/wire/modules/PageRender.module:356 0.0846 4947384 16. Wire->__call() www/wire/modules/PageRender.module:356 0.0846 4947384 17. Wire->runHooks() www/wire/core/Wire.php:320 0.0846 4949512 18. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.0846 4949680 19. TemplateFile->___render() www/wire/core/Wire.php:365 0.0847 4974624 20. require('www/site/templates/admin.php') www/wire/core/TemplateFile.php:169 0.0848 4975272 21. require('www/wire/modules/AdminTheme/AdminThemeReno/controller.php') www/site/templates/admin.php:15 0.0848 4975824 22. require('www/wire/core/admin.php') www/wire/modules/AdminTheme/AdminThemeReno/controller.php:13 0.0874 5362888 23. ProcessController->execute() www/wire/core/admin.php:93 0.0874 5363072 24. Wire->__call() www/wire/core/admin.php:93 0.0874 5363072 25. Wire->runHooks() www/wire/core/Wire.php:320 0.0874 5365200 26. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.0875 5365368 27. ProcessController->___execute() www/wire/core/Wire.php:365 0.8661 5455992 28. ProcessTemplate->executeRemoveFields() www/wire/core/ProcessController.php:213 0.8667 5495960 29. Fieldgroup->save() www/wire/modules/Process/ProcessTemplate/ProcessTemplate.module:1977 0.8667 5496176 30. Fieldgroups->save() www/wire/core/Fieldgroup.php:318 0.8667 5496528 31. Wire->__call() www/wire/core/Fieldgroup.php:318 0.8667 5496528 32. Wire->runHooks() www/wire/core/Wire.php:320 0.8667 5498344 33. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.8667 5498680 34. Fieldgroups->___save() www/wire/core/Wire.php:365 0.8670 5503608 35. FieldtypeInteger->deleteTemplateField() www/wire/core/Fieldgroups.php:196 0.8670 5504048 36. Wire->__call() www/wire/core/Fieldgroups.php:196 0.8670 5504048 37. Wire->runHooks() www/wire/core/Wire.php:320 0.8670 5506184 38. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.8670 5506608 39. Fieldtype->___deleteTemplateField() www/wire/core/Wire.php:365 0.8670 5507040 40. Fields->deleteFieldDataByTemplate() www/wire/core/Fieldtype.php:878 0.8670 5507480 41. Wire->__call() www/wire/core/Fieldtype.php:878 0.8671 5507480 42. Wire->runHooks() www/wire/core/Wire.php:320 0.8671 5509312 43. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.8671 5509736 44. Fields->___deleteFieldDataByTemplate() www/wire/core/Wire.php:365 0.8891 5512848 45. Pages->find() www/wire/core/Fields.php:536 0.8891 5513200 46. Wire->__call() www/wire/core/Fields.php:536 0.8891 5513200 47. Wire->runHooks() www/wire/core/Wire.php:320 0.8892 5515064 48. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.8892 5515400 49. Pages->___find() www/wire/core/Wire.php:365 0.8895 5519328 50. PageFinder->find() www/wire/core/Pages.php:199 0.8895 5519768 51. Wire->__call() www/wire/core/Pages.php:199 0.8895 5519768 52. Wire->runHooks() www/wire/core/Wire.php:320 0.8895 5521584 53. call_user_func_array:{www/wire/core/Wire.php:365}() www/wire/core/Wire.php:365 0.8895 5522008 54. PageFinder->___find() www/wire/core/Wire.php:365 I thought maybe the issue is that there is no page with the data (database table of field I am trying to delete is empty) so maybe there is some circular reference or something (I heard this can cause memory exhaustion)... but setting a few pages with some arbitrary value for the field didn't make any difference.
  13. kongondo, the code (for my delete.php template, which results in the memory exhaustion) is pretty much verbatim from your snippet in the thread I linked to above: https://processwire.com/talk/topic/7480-removing-a-field-from-database/?p=72039 if ($user->isSuperuser()) { //first remove the fields from 'user' template before deleting them. $t = $templates->get('user'); $fg = $t->fieldgroup; $fg->remove($fields->get('your_field')); $fg->save(); //delete the fields $f = $fields->get('your_field'); $fields->delete($f); }My 'your_field' is a plain integer field, and template ('user' in above code snippet) is the one with millions o' pages.Thanks for any insight you can provide.
  14. Hi pwired, It's related to a question I posted a couple of months ago (https://processwire.com/talk/topic/8604-how-to-build-pw-site-on-top-of-existing-database-that-keeps-changing/)... it's a feed-reading application with social features and whatnots. The people I am working with (and me most of all) might out of our league here, but I kept pushing them to pick Processwire and boy am I glad I did! One of the important features is searching through the 2+million pages by title etc, and it is really fast. There are of course other options (Solr/ Redis/ ?) if it slows down in another few million pages, but right now it is performing admirably. As for this empty field - after posting the above question I did poke around in the database, and saw that actually the extra field is taking up only 2-3 rows (in different tables) and an empty table for itself, even though theoretically it is 'added' to millions of pages. Very cool, and I figured I won't sweat it at the moment. (I want to create and delete a test field from a different template first, just to make sure... but it's not going to affect performance until I do, which is a relief.) I guess the above question has more relevance as a memory leak question maybe. I don't really know how to figure those out, so I'll leave this here in hopes someone who knows how to read the trace can help me understand what exactly happened.
  15. The field is empty, the template has over 2 million pages. So of course caution is necessary... I can't try anything too crazy. When I try to delete the field in admin area, as soon as I click on the confirmation checkbox and submit, it goes straightaway (fraction of a second) to a Bad Gateway 502 (nginx) error page. I also tried the API solution outlined by kongondo here: https://processwire.com/talk/topic/7480-removing-a-field-from-database/?p=72039 - it does not work, the script just stops running (again very quickly) at the save() part. Also tried deleting from the $fieldgroups api variable instead of from $templates. Same issue. Here is what I am getting from debug=true: Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 72 bytes) in /www/wire/core/PageFinder.php on line 306 Call Stack: 0.0000 242496 1. {main}()/www/index.php:0 0.0663 4512544 2. ProcessPageView->execute()/www/index.php:240 0.0663 4512896 3. Wire->__call()/www/index.php:240 0.0663 4512896 4. Wire->runHooks()/www/wire/core/Wire.php:320 0.0663 4515024 5. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0663 4515360 6. ProcessPageView->___execute()/www/wire/core/Wire.php:365 0.0721 4647600 7. Page->render()/www/wire/modules/Process/ProcessPageView.module:172 0.0721 4647784 8. Wire->__call()/www/wire/modules/Process/ProcessPageView.module:172 0.0721 4647784 9. Wire->runHooks()/www/wire/core/Wire.php:320 0.0722 4652776 10. PageRender->renderPage()/www/wire/core/Wire.php:387 0.0722 4653128 11. Wire->__call()/www/wire/core/Wire.php:387 0.0722 4653128 12. Wire->runHooks()/www/wire/core/Wire.php:320 0.0722 4655256 13. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0722 4655592 14. PageRender->___renderPage()/www/wire/core/Wire.php:365 0.0726 4696624 15. TemplateFile->render()/www/wire/modules/PageRender.module:356 0.0726 4696808 16. Wire->__call()/www/wire/modules/PageRender.module:356 0.0726 4696808 17. Wire->runHooks()/www/wire/core/Wire.php:320 0.0726 4698936 18. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0726 4699104 19. TemplateFile->___render()/www/wire/core/Wire.php:365 0.0727 4723816 20. require('/www/site/templates/delete.php')/www/wire/core/TemplateFile.php:169 0.0742 4726296 21. Fieldgroups->save()/www/site/templates/delete.php:14 0.0742 4726648 22. Wire->__call()/www/site/templates/delete.php:14 0.0742 4726648 23. Wire->runHooks()/www/wire/core/Wire.php:320 0.0742 4728464 24. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0742 4728800 25. Fieldgroups->___save()/www/wire/core/Wire.php:365 0.0745 4733760 26. FieldtypeInteger->deleteTemplateField()/www/wire/core/Fieldgroups.php:196 0.0745 4734200 27. Wire->__call()/www/wire/core/Fieldgroups.php:196 0.0745 4734200 28. Wire->runHooks()/www/wire/core/Wire.php:320 0.0745 4736336 29. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0745 4736760 30. Fieldtype->___deleteTemplateField()/www/wire/core/Wire.php:365 0.0745 4737192 31. Fields->deleteFieldDataByTemplate()/www/wire/core/Fieldtype.php:878 0.0745 4737632 32. Wire->__call()/www/wire/core/Fieldtype.php:878 0.0746 4737632 33. Wire->runHooks()/www/wire/core/Wire.php:320 0.0746 4739464 34. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0746 4739888 35. Fields->___deleteFieldDataByTemplate()/www/wire/core/Wire.php:365 0.0754 4743128 36. Pages->find()/www/wire/core/Fields.php:536 0.0754 4743480 37. Wire->__call()/www/wire/core/Fields.php:536 0.0754 4743480 38. Wire->runHooks()/www/wire/core/Wire.php:320 0.0754 4745344 39. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0754 4745680 40. Pages->___find()/www/wire/core/Wire.php:365 0.0758 4749608 41. PageFinder->find()/www/wire/core/Pages.php:199 0.0758 4750048 42. Wire->__call()/www/wire/core/Pages.php:199 0.0758 4750048 43. Wire->runHooks()/www/wire/core/Wire.php:320 0.0758 4751864 44. call_user_func_array:{www/wire/core/Wire.php:365}()/www/wire/core/Wire.php:365 0.0758 4752288 45. PageFinder->___find()/www/wire/core/Wire.php:365 Hope this is enough information for one of you seasoned folks to help me out.Thanks in advance!
  • Create New...