Leaderboard
Popular Content
Showing content with the highest reputation on 05/03/2016 in all areas
-
Users are pages, but in the Users section of the admin there isn't the same support for unpublished users as for unpublished pages. When users register on the frontend I set their status to unpublished until their email address is validated (thanks to a suggestion in the forums from Soma). But while users are unpublished it isn't possible to make edits to their profile via admin because there is no "Save and keep unpublished" button like there is for other pages. To save changes in admin the user must become published. Also, there is no ability to unpublish a user from admin. This would be a useful option if a user account needs to be suspended rather than deleted. Edit: another small thing that would be nice to have is for the user list to honour the useHoverActions config preference for PageList. I keep hovering on the user list and then I remember I have to click the name to get the flyout links.5 points
-
Hi, I just made this module because I needed it. GitHub: https://github.com/blynx/AdoptDefaultsFromParents Module Directory: http://modules.processwire.com/modules/adopt-defaults-from-parents/ What it does: It fills fields of newly added pages with corresponding field-values of their parents. Configurable by setting "giving templates" and "adopting fields". Configuration: You have to set templates which are able to give field values and fields which are able to receive values. Then, this module automatically applies field values to every newly added page from their parents according to those settings. Also you can switch between immediate or closest parent (@LostKobrakai, thanks for the hint!) Why: I am building a little webshop with padloper and made some product categories ("parent page") which have some properties which should be automatically descendable to their children. Yet, the children should be able to have individual values if they want to. Now: So far it works for me - but please test it out and if you think improvements can be made, tell me about it. Also, what do you think about the general idea? Notes: So far I haven't tested it with more complex fields, yet. So far tested and working: Integer Text Page Similar fields should work. The module simply copies the field value. cheers! UPDATES v003 - 10.5.2016 Added option to switch between immediate or closest parent4 points
-
You could try to use the new ajax-driven inputs (more on that here). Basically you can tell Processwire to delay loading of some specific inputs (or groups of inputs) until they are opened/selected. Worth a try in your case. Let me know3 points
-
Good news! (ProCache and AIOM) In regard of the image variations, maybe you can provide a hook, so that others are able to add a functionality?3 points
-
I'm planning to support ProCache and AIOM. But not sure I want to mess at all with image variations. I also don't see that as a cache and think the developer should take care of that depending on the project.3 points
-
Thanks @mr-fan, I'm familiar with that thread and I am activating users via an email link. But in principle I think unpublished/published users is the ideal way to have users in an inactive/active state. That's what the published status of a page is for, so it shouldn't be necessary to add a new field for the same purpose. And it also has the benefit of preventing login and view access for unvalidated user accounts without the need for additional logic in login functions and page templates.2 points
-
Also try Autocomplete which only fetches the populated pages instead of the whole list. This speeds things up too.2 points
-
Thanks for the module! Another approach to inherit the values of parent page fields: $foo = $page->foo ?: $page->closest("foo!=''")->foo; So if field "foo" is empty for the current page $foo gets the value of the closest parent in which field "foo" is not empty. Not to say this is as flexible as your module approach though.2 points
-
Hi Jürgen, I was looking for something like this and built something similar which is more generic I guess - but I haven't tested it with complex fields so far. In my module it is possible to set specific templates which are able to "give" field values and specific fields which are able to receive values. Then, any field of a newly added page adopts those values according to the settings. https://processwire.com/talk/topic/13183-adopt-field-values-as-defaults-from-parents/ Maybe this might also be useful for you. best wishes Steffen2 points
-
Thanks guys... I located the raw date problem... During the last commit to allow use of date format specified in blog_comments to be displayed for comments I forgot that on a fresh install, one has to first save what is specified in FieldtypeComments's dateFormat for that to kick in (see the fields Details Tab). The default 'relative' is not saved unless the user actually saves the field (normal for fields). So, in our case, the dateFormat was empty and as a fall-back, you were being shown the unformatted date as per line #247 in WireDateTime formatDate(). I've committed a fix. Update: Blog 2.3.9 Fixes above bug PS: There's still 1 or 2 pending requests that I haven't yet gotten time to address...2 points
-
Can you remove each field one at a time and test the edit ability at each step?2 points
-
2 points
-
This module allows you and your site editors to protect a page (and optionally its children, grandchildren etc) from guest access directly from the page's Settings tab. You can also limit access to certain roles. http://modules.processwire.com/modules/page-protector/ https://github.com/adrianbj/PageProtector It makes it very easy for editors to set up various password protected areas on their site, or to simply protect a new page or section while they are still working on it. Ability for your site editors to control the user access to pages directly from Settings tab of each page Include whether to protect all children of this page or not Optionally allow access to only specified roles Option to protect all hidden pages (and optionally their children) Ability to change the message on the login page to make it specific to this page Option to have login form and prohibited message injected into a custom template Access to the "Protect this Page" settings panel is controlled by the "page-edit-protected" permission Table in the module config settings that lists the details all of the protected pages Shortcut to protect entire site with one click In addition to the admin interface, you can also set protection settings via the API: // all optional, except "page_protected", which must be set to true/false // if setting it to false, the other options are not relevant $options = array( "page_protected" => true, "children_protected" => true, "allowed_roles" => array("role1", "role2"), "message_override" => "My custom login message", "prohibited_message" => "My custom prohibited access message" ); $page->protect($options); As alway, I would love any feedback / suggestions for improvements. Hope you find it useful! Page Protection Settings (settings tab for each page) Module Config Settings1 point
-
This module is deprecated in favor of RockMigrations. It'll continue to work and I might fix some smaller incompatibilities if they're reported, but no major development will happen on this anymore. There where various threads about a how to reasonably handle multiple dev/staging and live environments with ProcessWire and at best handle it as automatically as possible. A git based workflow makes it easy to handle files, but the pain point of migrating db changes has even lead to multiple requests of not handling template/field storage in the db at all. I've gone ahead and used for my own projects the concept of database migrations, which most frameworks are using to handle database changes – but the ProcessWire flavored way. ___ ___ ___ ___ ___ ___ ___ /\__\ /\ \ /\ \ /\ \ /\ \ /\ \ /\ \ /::L_L_ _\:\ \ /::\ \ /::\ \ /::\ \ \:\ \ /::\ \ /:/L:\__\ /\/::\__\ /:/\:\__\ /::\:\__\ /::\:\__\ /::\__\ /::\:\__\ \/_/:/ / \::/\/__/ \:\:\/__/ \;:::/ / \/\::/ / /:/\/__/ \:\:\/ / /:/ / \:\__\ \::/ / |:\/__/ /:/ / \/__/ \:\/ / \/__/ \/__/ \/__/ \|__| \/__/ \/__/ Beta This module does help you managing migration files, where any database changes can be stored in php files using just the simple ProcessWire api at your disposal. It's not as nice as using the admin UI, but certainly better than trying to migrate changes manually and possibly weeks after adding the changes. Also there's always the option to create helper modules, which can export changes made in the admin UI to something usable in those migration files. For example I'm using an internal process module, which does let me export changes to template access rules as json strings, which I then use in my migrations to actually apply the changes. Now on to the meat – How to use the module: Read the following guide on creating own migrations Maybe use the CLI tool to speed up your workflow (and possibly automate stuff) It is generally recommended, but not enforced, that migrations are run/rolled back in order. When doing migrations or rollbacks, without specifying a migration, this module will stick to the order. Creating Migrations Your migrations will probably hold lot's of code, which does delete data. By now this module does not have any security measurements to prevent that. Be sure to test your migrations locally and possibly keep a database backup before running them. There are currently four types of migrations: default (Migration) Default migrations are the most free form migrations. There's just a description and two functions – update() and downgrade(). What you're doing in those functions is totally up to you, but it's recommended to try the best to keep changes as reversible as possible. Meaning that running update() and downgrade() once should have as less effect on the installation as possible. The ProcessWire API is available exactly like in modules using the $this->pages, $this->config, … syntax. FieldMigration TemplateMigration ModuleMigration All of those are there to make your life easier. They all have different but similar functions – which you can find in migrations created by this module – which ease the creation and removal of fields, templates or modules. All the boilerplate is handled by the base classes these migrations do extend, so you don't even need to think about update() and downgrade(). You can rather just describe the item you want to handle and the creation / removal process is taken care of. These are by now not highly tested, so please again be sure to test migrations before running them on important content. Command-Line Interface The module does include a cli interface, which does allow the migrations to be run automatically by CI or deployment scripts or just by you if you like cli's. The cli script is located in the bin directory inside the module's folder. It does however require a composer package to work, which you can simply add by running composer require league/climate in your site directory (or the root directory for pw 3.0). Make sure to require composers autoload.php in your config.php for 2.x installations. The CLI does have a quite handy help page, which you get by running php migrate -h so I'm just adding the important bits of that here: > php migrate -h […] Usage: migrate [-h, --help] [-i info, --info info] [-m migrate, --migrate migrate] [-n new, --new new] [-nf newField, --newField newField] [-nm newModule, --newModule newModule] [-nt newTemplate, --newTemplate newTemplate] [-r rollback, --rollback rollback] Optional Arguments: -m migrate, --migrate migrate Run a specific migration or all new* ones if none given. * From latest migrated to newest. -r rollback, --rollback rollback Undo a specific migration or the latest one if none given. -n new, --new new Bootstrap a new migrations file. Optionally you can already supply a description. -nt newTemplate, --newTemplate newTemplate Bootstrap a new template migrations file. Optionally you can already supply a description. -nm newModule, --newModule newModule Bootstrap a new module migrations file. Optionally you can already supply a description. -nf newField, --newField newField Bootstrap a new field migrations file. Optionally you can already supply a description. -i info, --info info Get detailed info about a migration. -h, --help Show all commands of the cli tool. Link the migrations cli update save to ProcessWire's root: https://processwire.com/talk/topic/13045-migrations/?p=118329 Helper Functions There are already a handful of helper function included in the Migration base class, which tackle things I found to need way to much boilerplate for kinda simple changes, but you can also add own custom helper functions via hooks. /** * This does use @diogo's while loop technique to loop over all pages * without getting memory exhaustion. */ $this->eachPageUncache("template=toBeHidden", function($p){ $p->setAndSave('status', Page::statusHidden); }); /** * $template, $field, $reference = null, $after = true * The below function reads like this: * In the template … add the field … relative to the field … in the position after/before */ $this->insertIntoTemplate('basic-page', 'images', 'body', false); /** * Edit field settings in context of a template */ $this->editInTemplateContext('basic-page', 'title', function($f, $template){ $f->label = 'Headline'; }); And a simple example of adding a custom helper as a hook. // in ready.php $wire->addHook('Migration::renameHome', function(HookEvent $event){ $name = $event->arguments(0); wire('pages')->get('/')->setAndSave('title', $name); }); // in the migration $this->renameHome('Root'); Snippets Still not sure how all this works in practice? Or you want to share a maybe more complex migration? Just head over to the Snippets Repo at Github. https://github.com/LostKobrakai/MigrationSnippets There are also less specific examples in the modules repository: https://github.com/LostKobrakai/Migrations/tree/master/migrations Appendix As long as the module is in Beta the helper functions in the Migration.php might be object to change/removal, so be aware of that. Download http://mods.pw/Bm https://github.com/LostKobrakai/Migrations1 point
-
Hello @ all I want to share my code of a module which copies values from a parent page to a child page by using the add button of a pagetable field. If you find it useful you can copy the code or you can improve the code and post your ideas of improvement here. The intention for me was that I have pages with events and I dont want to write all the data for an event manually. Especially if only the date of the event is different. I use a pagetable field for the events and I want to click the add button of this field and a new childpage will be created with all the data of the event (title, description, summary,...) so I have only to fill in the start and end date for the event. So far so good, but it was a little bit tricky to get this to work with the add button of the pagetable field. So I decided to write a module which does the work for me. Here is the piece of code: <?php class CopyPageTableAdd extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Pagetable copy values', 'summary' => 'Copy Pagetable content by pressing the add button', 'href' => '', 'version' => 001, 'autoload' => true, 'singular' => true ); } public function ready() { $this->pages->addHookBefore('ProcessPageAdd::execute', $this, 'copyaddpage'); } public function copyaddpage() { //configuration $parenttemplatename = "events"; //the template name of the parent template $childtemplatename = "single-event"; //the template name of the newly created child template $page = new Page(); $page->parent = $this->input->get->parent_id; if ($page->parent->template == $parenttemplatename) {//check if it is the right parent template $page->template = $childtemplatename; //set the template for the created child page //copy all fields field values from the parent template (start) //enter all fields which you want to copy into the child page $page->title = $page->parent->title; $page->eventstatus = $page->parent->eventstatus; $page->eventtype = $page->parent->eventtype; $page->summary = $page->parent->summary; $page->headline = $page->parent->headline; $page->importanteventstext = $page->parent->importanteventstext; $page->importanteventstext = $page->parent->importanteventstext; $page->notifiable = $page->parent->notifiable; $page->reservationtype = $page->parent->reservationtype; $page->participantlimit = $page->parent->participantlimit; $page->participantmaxnumber = $page->parent->participantmaxnumber; $page->eventmaxstatus = $page->parent->eventmaxstatus; $page->eventcosttype = $page->parent->eventcosttype; $page->eventprice = $page->parent->eventprice; $page->eventpriceadd = $page->parent->eventpriceadd; $page->eventlocationname = $page->parent->eventlocationname; $page->street = $page->parent->street; $page->postalcode = $page->parent->postalcode; $page->eventlocationname = $page->parent->eventlocationname; $page->place = $page->parent->place; $page->region = $page->parent->region; $page->country = $page->parent->country; $page->googlemap = $page->parent->googlemap; //copy all fields field values from the parent template (end) $page->addStatus(Page::statusUnpublished); //this foreach loop is only if you have a multilanguage site to get the path names in each language //if your site is only single language you can use $page->name=$page->parent->name (but not tested) foreach ($this->languages as $lang) { $lname = $lang->id; $pageName = $page->title->getLanguageValue($lang); $page->set("name$lang", $pageName); if ($lang->isDefault()) continue; $page->set("status$lang", 1);//activate the multilanguage checkbox } $page->save(); $this->session->redirect("../edit/?id=$page"); } } } The configuration part: //configuration $parenttemplatename = "events"; //the template name of the parent template $childtemplatename = "single-event"; //the template name of the newly created child template This is the part where you have to define the templates. The name of the parent template is responsible that the module only run on that template (in my case the template with the name "events). The name of the child template ist the template which should be created after pressing the add button (in my case the template with the name "single-event"). You have to fill in your template names. The module runs only if the parent template has the specific name and creates only child pages with the child pages template name. Copy all field values par: //copy all fields field values from the parent template (start) //enter all fields which you want to copy into the child page $page->title = $page->parent->title; $page->eventstatus = $page->parent->eventstatus; $page->eventtype = $page->parent->eventtype; $page->summary = $page->parent->summary; $page->headline = $page->parent->headline; $page->importanteventstext = $page->parent->importanteventstext; $page->importanteventstext = $page->parent->importanteventstext; $page->notifiable = $page->parent->notifiable; $page->reservationtype = $page->parent->reservationtype; $page->participantlimit = $page->parent->participantlimit; $page->participantmaxnumber = $page->parent->participantmaxnumber; $page->eventmaxstatus = $page->parent->eventmaxstatus; $page->eventcosttype = $page->parent->eventcosttype; $page->eventprice = $page->parent->eventprice; $page->eventpriceadd = $page->parent->eventpriceadd; $page->eventlocationname = $page->parent->eventlocationname; $page->street = $page->parent->street; $page->postalcode = $page->parent->postalcode; $page->eventlocationname = $page->parent->eventlocationname; $page->place = $page->parent->place; $page->region = $page->parent->region; $page->country = $page->parent->country; $page->googlemap = $page->parent->googlemap; //copy all fields field values from the parent template (end) This ist the part where you can fill in all fields which you want to copy the values. It copies the values from the parent page to the child page. You can do this also with a foreach loop, but I dont want to copy all field values so I write it manually for each field. The multilanguage part: foreach ($this->languages as $lang) { $lname = $lang->id; $pageName = $page->title->getLanguageValue($lang); $page->set("name$lang", $pageName); if ($lang->isDefault()) continue; $page->set("status$lang", 1);//activate the multilanguage checkbox } The multilanguage part is necessary if you have a multilanguage site, because it creates the path names for each language in the right language. After that the multilanguage checkbox for the non default language should be checked to activate the page in this language. Here are some screenshots: 1) Press the add button of the pagetable field 2) A new child page will be created with prefilled values of the parent page 3) Path names are in the right language and multilanguage checkbox is activated So this might be useful for others Best regards1 point
-
I just committed a new version - it now ignores pages under admin and trash. Before it just excluded pages with the "admin" template. I think this should take care of the problem with WireQueue. I also fixed a bug with images being blank in RTEs when you haven't manually specified the max number of images for the images field that is used.1 point
-
You could go with a activation link via email - so you can simple validate new users and set them activ via a email link...or in the backend and by setting activate_user to sero...or go with two different roles user_active and user_pending....you have multiple options to implement a comfortable managment via Lister pro or something else... link for a really good activation solution: https://processwire.com/talk/topic/4066-activate-user-account-via-email/ regards mr-fan1 point
-
Hi, 1) Dates might be broken due to output formatting 2) You can acces the fields of the repeater, like you would do with a page. $p = $pages->get("/path/to/currentParent"); $rf = "repeater_field"; //repeater field name $pt = "basic-page"; //page template name foreach($p->$rf as $r){ $r->of(false); //Should make sure raw data are copied. (dates) $np = new Page(); $np->of(false); $np->template = $pt; $np->parent = $p; foreach($r->fields as $f){ $np->$f = $r->$f; } $np->title = $r->field1 + $r->field2 //that's how you should be able to access repeater fields and set the title $np->save(); }1 point
-
Take a look at the links for the action buttons in the admin. To unpublish for example, looks like: http://pw.dev/processwire/page/?action=unpub&id=1005 Presumably the users with access to these links will be logged in and their role will have permission to perform these actions?1 point
-
$p = $pages->get("/path/to/currentParent"); And make sure $p is the correct page.1 point
-
Just a note, closest() isn't even needed here, because we already know the current page doesn't have a value for foo. ->parents("foo!=''") will do the same excluding the current page from the possible resultset. It's rather this where closest() shines. $foo = $page->closest("foo!=''")->foo1 point
-
That's basically the approach I used here: https://processwire.com/talk/topic/10817-field-inheritance/ The benefit of it is, that the field can stay empty and will therefore automatically adopt any changes to the parent page's value as long as it doesn't have an own value specified.1 point
-
Solved now - $sanitizer->textarea works just fine with no options needed. I just couldn't see the line breaks because I put the plain text message in WireMail's bodyHTML.1 point
-
@teppo: we definetly need two versions. I think, to clear all at once is the more common one and should have priority. A per/page solution may come later. @tpr: that's the question. I don't have experiences with RTE's and images. I know that Ryan has done something to be able to recreate variations in RTE's. But I don't know when and in what extend. Think of these use cases: variation from an imagefield of the same page variation from an imagefield of another page The first one can be covered, if I remember right on what I have read from Ryan (don't know where I have read it) The latter one I don't know. We need to test thouroughly, I think, or ask Ryan what is currently covered and what not. There are three different types: original images image variations orphaned imagefiles Only the variations belong to the Cache.1 point
-
When removing all image variations, is the removal of CKEditor images safe now? I occassionally use horst's "PageimageRemoveVariations" module that comes with a big warning:1 point
-
Again it boils down to differences in use cases. I don't think any of our sites have a single page with even close to a hundred images, let alone that amount of variations. I would assume that this requires some tricks either way; from my point of view variations are temporary data, so one should always be prepared for them going away, and generating hundreds of variation images at one go sounds like an extremely resource-intensive task. If I had this kind of need, I'd probably try to figure out some method of creating the variations as a background task before the page (or images without variations) can become publicly viewable Anyway, I'm not saying that this isn't a feasible situation, just that it's something none of our sites have. For us it's common to have hundreds or thousands of pages with a few images at tops, in which case a method of cleaning out all variations would be quite handy. On the other hand for use cases like the one you've mentioned above a page-by-page solution would make more sense. Perhaps two separate solutions would make most sense? Not sure if clearing unused variations is really feasible, considering how they're requested, but of course that would be nice if it was feasible..1 point
-
1 point
-
@heldercervantes For images, look at removeAll() for getting rid of everything in the field or just removeVariations() to kill off the size variations.1 point
-
There's no difference in how you would use $session, $input, or any API variable or any PHP superglobal ($_GET, $_POST, etc). These have nothing to do with namespace. If you must disable the template compiler, edit your /site/config.php and add $config->templateCompile = false; to it. That will prevent any of your template files from getting compiled. As for compiling modules: At this time I wouldn't recommend disabling the module compiler, otherwise almost no 3rd party modules will work. That's because there are few if any PW3-specific modules at present. If you come across a module that isn't working after being compiled, let me know about it so I can investigate it. When it comes to template files (and you've disabled the template compiler): you don't need to add a namespace to all of them. You only need to add it to those that are calling ProcessWire specific functions like the wire() function, or those that are referring to ProcessWire constants or classes directly. Things like this: $foo = new PageArray(); $date = wireDate('Ymd'); $page->addStatus(Page::statusUnpublished); The parts in bold above are those that are referring to things in the ProcessWire namespace. Adding "namespace ProcessWire;" to the top of the file makes it simple, that's all you'd have to do. If you didn't want to do that, you could also just update a wire() function call to be like this: $date = \ProcessWire\wireDate('Ymd'); Or you could just enable the template compiler, which will do this for you. However, maybe you aren't using things like the wireDate() or wire() functions and maybe you aren't referring to things like Page::statusUnpublished. If that's the case, you can skip adding a namespace at all, and likewise don't need the compiler. ProcessWire's API variables like $pages and $input and $session and all of that are going to be present either way. These have nothing to do with namespace.1 point
-
You simply do nothing and it should work exactly like beforehand. That's 90% of the reason the file compiler does exist in the first place. So the question is rather why it doesn't work for you.1 point
-
That's expected. The chosen library was created to be a seemless enhanced select field (meaning it will be fully useable without js), which is why it does not have any ajax capabilities and therefore has the same problem as all other non ajaxy inputfields when loading a ton of pages.1 point
-
Depends a lot on the use case. I'm currently working on a site with roughly 10.000 pages, and because of some recent changes, most of those pages have a whole bunch of unused image variations. Per-page solution wouldn't do me much good here Generally speaking I'd say that a "clear all imagevariations" would be more useful than a per-page option.1 point
-
What's the missing 10% ? Did the field pairings work as expected? Is there anything I can do to make BCE work better for your needs?1 point
-
What kind of fields do you have in those repeaters ? is 'names' maybe a select field, where it has to load all values of that select ? And if so, try to use autocomplete.1 point
-
A couple of ways I have dealt with static file versioning in PW: 1. Use AIOM+ for your CSS and JS files. AIOM+ is sensitive to what is contained in your files though - I got an error when my CSS contained a background image path to a PHP script (for generating translucent PNGs for older browsers that don't support rgba colours). 2. A function that renames static files according to the last modified time (adapted from this article). Include somewhere before your template head is generated... function autoVer($url){ $name = explode('.', $url); $lastext = array_pop($name); array_push($name, filemtime($_SERVER['DOCUMENT_ROOT'].$url), $lastext); $fullname = implode('.', $name); echo $fullname; } Use as follows for your CSS and JS... <link rel="stylesheet" href="<?php autoVer('/site/templates/css/mystyles.css'); ?>"> <script src="<?php autoVer('/site/templates/js/myscript.js'); ?>"></script> Add to your .htaccess, after "RewriteEngine on"... # Versioned static files RewriteCond %{REQUEST_FILENAME} !-s RewriteRule ^(.*)\.[\d]+\.(css|js)$ $1.$2 [L]1 point
-
Hello! I read a lot about the ImageSizer class from processwire, because I want to contribute to get better image resizing. Processwire (horst in special) has implemented a gamma correction before resizing images. Why this has to be done is explained here: http://www.4p8.com/eric.brasseur/gamma.html . I have this link also from a post from Horst. Now I stumbled upon a bug that causes to loose image information. This is the function I am talking about in ImageSizer.php protected function gammaCorrection(&$image, $mode) { if(-1 == $this->defaultGamma || !is_bool($mode)) return; if($mode) { // linearizes to 1.0 if(imagegammacorrect($image, $this->defaultGamma, 1.0)) $this->gammaLinearized = true; } else { if(!isset($this->gammaLinearized) || !$this->gammaLinearized) return; // switch back to original Gamma if(imagegammacorrect($image, 1.0, $this->defaultGamma)) unset($this->gammaLinearized); } } This function uses the gd-lib function imagegammacorrect to set the gamma value to 1.0 before resizing and set it back after resizing. The imagegammacorrect function provides a datatype int, which has on my server the size of 8 bits, just enough to store a picture that also stores each pixel in 8 bit value. What the imagegammacorrect function does: It exponentiates each pixel-value of the image with the gamma value entered (2.0 by default on pwire). Then it resizes the image. After that to set back the gamma it exponantiates with the inverse value that was before exponentiated. (1/2.0=0.5 with default value). Because only integer (8bits) is provided the function is rounding the values and makes some error. Here is my test picture (2400x2400 pixels) I resized every image to 300x300 pixels. Here are the resized ones with different gamma values: Gamma function omitted Gamma value 2.0 (standard) Gamma value 3.0 Gamma value 4.0 Now I was curious if I could reconstruct the error in an other program. So I wrote a little script in Matlab and did the same. Heres the script: % load image [img,map,alpha] = imread('gamma_dalai_lama_gray.jpg'); %imshow(img, 'InitialMagnification', 100); gamma = 2; scale_factor = 300/2400; figure(1); imshow(img, 'InitialMagnification', 200); figure(2); tmp = double(img).^gamma; img_gamma = uint8(tmp./((255^gamma)/255)); img_resized = imresize(img_gamma, 0.5); tmp2 = double(img_resized).^(1/gamma); img_gamma = uint8(tmp2./((255^(1/gamma))/255)); imshow(img_gamma, 'InitialMagnification', 400); imwrite(img_gamma, 'testbild_300_gamma_2.0.jpg'); Here's the result pictures: Gamma value 2.0 (with matlab) Gamma value 3.0 (matlab) Gamma value 4.0 (matlab) Theoretical we would need more than 8bits per pixel to not loose any data. That would be for Gamma 4.0: (2^8)^4=32bits per pixel. Or for Gamma 2.0: (2^8)^2=16bits per pixel. I don't know how to solve this problem in php so I'm writing in here in the hope someone has a good solution or a hint what I'm doing wrong... Processwire Version 2.5.3 PHP-Version is 5.6.0 If you need more informations let me know. Edit: My integer size has not the size of 8bits that was 8bytes so 64bits... But as I confirmed with matlab script there is an 8bit cropping going on, maybe in the gd-lib? Edit: I think I found out where this is caused. It's in the php sources (php-src/ext/gd/gd.c on line 3133). The cropping happens, because an integer is used instead of a double or float value (the dark pattern in my test image gets even darker with gamma correction). My suggestion is to take out the Gamma Correction and contribute code to GD-Lib to implement it there. With plain php we can't make it better for now.1 point
-
Nice one Adrian! Minor suggestion, maybe add a note/description to the setting 'Protect children' that the protection cascades to grandchildren, etc.1 point
-
Or you could use this undocumented feature: Edit your /site/config.php and set $config->advanced = true; In your admin, go to Setup > Templates > your-post-template Click to the "System" tab. See the last field: "Allow the created user to be changed on pages?" Check that box and Save. Restore your config.php back to normal: Edit your /site/config.php again and set $config->advanced = false. Now you should be able to change the "Created User" on the Settings tab of any pages using that template.1 point
-
Just thought you guys might like to know that the priority setting just got another user Needed to solve the conflict between RedirectIds and 404Search modules. Thanks again Ryan for thinking of everything!1 point
-
This line failed to load a user: $u = $users->get($uid); User ID 40 doesn't exist in the system because anytime PW returns a NullPage that means it didn't find what you were looking for. The best way to check if you got a NullPage is to see if the returned has an ID. So your last section of code should be something like this: if ($u->id && $u->hasRole($role)){ ...stuff } Btw, ID 40 is the default ID for the 'guest' user account, so it would be unusual if that really is the ID of the user and it didn't load.1 point