Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/13/2018 in all areas

  1. Velotraum is a small German manufacturer, building rather costly, individually manufactured bicycles for both globetrotters and everyday bikers. We use RepeaterMatrix for long structured texts, and we use a lot of individual fields for metadata. We even built our own "preview" function for blog comments and included Textile light for blog comments, too. Have a look: velotraum.de
    10 points
  2. @Loges: Somewhere in the middle of my (unfortunately growing) todo list is a field encryption module (or, precisely, a whole set of them for different scenarios). The bad news is that it's been there for a while and regularly been overtaken by reality (speak crypto api changes, now a badly under-documented libsodium, breached algorithms, etc.) and I've been hesitant to roll out something that might not be future-proof. You should be able to implement something quickly though if you don't aim for a generic, fool-proof-in-any-environment solution. With PW's hooks api, you could even add encryption to existing field types like FieldtypeText and its descendants. Here's a short rundown of my thoughts that might get you started with your own module: Use symmetric encryption, store your key in a property in site/config.php, make sure to avoid insecure combinations like AES256 with ECB You need at a minimum the following hooks: FieldtypeText::sleepValue where you encrypt the field values for storage in the DB. Be aware that the value passed to that might either be a string or an array of strings (in multi language sites), each of which you need to encrypt. FieldtypeText::wakeupValue where you decrypt the db values for use inside PW. You get either a string value or a LanguagesPageFieldValue object (multi language sites) for which you need to decrypt the value for every language (use getLanguageValue/setLanguageValue). FieldtypeText::getConfigInputfields to add a property (InputfieldCheckbox) that determines whether to use encryption (and is checked inside sleepValue/wakeupValue) in the field's configuration Use a truly random initialization vector (IV) for encryption, which is, depending on PHP version and configuration, sometimes harder than it sounds. Of course, back up your encryption/decryption key really good
    6 points
  3. Hey everyone! It's been a while since I last had a time to work on this module. But now I finally managed to focus on this module. So here are the latest updates. The codebase of the module grew very big and the more features I added the more time I had to spend to make sure the changes I made does not break anything. Because I had to manually verify if everything works as expected. After long night hours of trial and error I managed to setup tests for this module. Tests will help us quickly add/remove features as needed, because now there is no need for manually verifying all edge cases. Also I setup the Travis-CI so people can contribute more confidently and I can merge pull requests without worrying! There are already bunch of tests, but there is still some I'll be adding. ? ? I will add some documentation on how to run tests locally in github wiki pages soon and let you know here. Another thing to note is that the master branch of our module no longer tracks the vendor code. This means that if you download the master branch and put it into your /site/modules directory it will not work. Instead you should use release builds that are a cleaned version of the module. It includes required vendor codes and does not have extra files that are not relevant to ProcessWire. Like presentation gif images, test files and so on. This makes the module size smaller!
    5 points
  4. Welcome to the forums @activestate. Have a read here about selectors, specifically about MySQL and short words. Please use code blocks (@see the <> icon) around your code.
    4 points
  5. I just wanted to follow-up for anybody reading in a similar situation. After spending more time with the admin and understanding things I can say using it as opposed to recreating an admin at the 'frontend' is 100% the way to go, will be saving a ton of time, so glad I got a good steer from you all.
    4 points
  6. Dunno if it's still valid (long time ago), but this thread might be relevant
    3 points
  7. It's kinda hacky, but this does work: $this->addHookAfter('Page::render', function($event) { if($this->process != 'ProcessPageEdit') return; $p = $this->process->getPage(); $headline = "My ID is $p->id"; $event->return = str_replace($p->title.'</h1>', '<strong><em>'.$headline.'</em></strong></h1>', $event->return); });
    3 points
  8. @adrian, I created a pull request for adding support for Repeater Matrix to the "Copy Repeater Items to Other Page" action. It only required a small modification to the field select options so I thought it best to keep this within the existing action rather than create a new action just for copying Repeater Matrix fields. I thought about allowing all fieldtypes that extend FieldtypeRepeater but decided it would be better to add fieldtypes on a case-by-case basis just in case someone has a custom fieldtype that extends FieldtypeRepeater in some weird and wonderful way that wouldn't be compatible with the action. I also added a couple of other enhancements to the action - failure conditions for if the selected repeater field doesn't exist on the source or destination pages (previously the action reported a success in those cases). And copying repeater items now also copies any files or images included in the repeater items. One last thing I added, to the module itself this time, is a link to the module config settings in the notice that advises that new actions are available. I think it would also be handy to have a link the config settings in the process page - I often want to jump there to adjust allowed roles and the "in menu" option. I didn't include this in the pull request though - just something for you to consider.
    3 points
  9. Hey community! Anybody worried about the new regulation? From May 25th on, we better start complying, otherwise there's an "up to 4% of the year's turnover or 20 Million euro fine, whichever greatest" hanging over our heads. Most my projects don't store any data and the forms only submit to email. I can't find any information regarding this scenario, but I'm guessing we'll need to add disclaimers in a privacy policy that clearly answers these questions: https://goo.gl/iczesa, and a checkbox for accepting the terms. I'm curious though about how something like privacy by design could be implemented in PW. Looks like it's time to send proposals to all our previous clients
    2 points
  10. Yeah, that module wouldn't really be practical if you need more than one or two virtual parents. The Virtual Parents module was an experiment to answer the question "To what extent is it possible to trick ProcessPageList into showing a page structure that isn't real?" And now that I've tried it I can answer with "To only a very limited extent". ProcessPageList just isn't designed to support anything other than the real page tree and forcing it do otherwise is pretty painful. There have been several requests for a way to browse an alternative page structure. It will require a module that builds its own tree from scratch and doesn't rely on ProcessPageList. It's on my to-do list but it will be challenging and I'm not sure when I'll get to it. And bear in mind too that any module like this will come with other limitations - for instance, it wouldn't be possible to sort or move pages like ProcessPageList can because the page structure shown might have no resemblance to the real structure.
    2 points
  11. OpenSSL is just one possibility. I've also used phpseclib and am just in the process of figuring out libsodium, but all should be viable tools there. I guess standard AES256 and CBC mode should both be sufficiently secure and reasonably well documented, and openssl_random_pseudo_bytes should likely be safe enough in an up-to-date setup. Yes, you can either encrypt or search. I guess offloading en-/decryption to the database server would be possible with specialized field types, but searches would be absolute performance killers (all such fields would have to be decrypted in-memory, then flat table scans would have to be performed).
    2 points
  12. More precisely, it create a new InputfieldMarkup and add it to the LoginRegister form. You can put any markup you want inside this field. Compare and try with this code : wire()->addHookAfter('LoginRegister::renderMessage', function ($event){ $message = $event->return; // get the original message // bd($message); // use TracyDebugger to get whats inside the variable - now we know how to modify the markup $message = str_replace("</p>", " (<a href='". wire('pages')->url ."?logout=1'>" . __('Logout') . "</a>)", $message); // replace markup $event->return = $message; // set the modified value back to the return value }); https://processwire.com/blog/posts/introducing-tracy-debugger/ https://www.google.com/search?q=processwire+get+started+with+hooks
    2 points
  13. Ahhhh, this is the ticket Thank you muchly sir
    2 points
  14. Just ran the copy repeater matrix action. Works great, thanks again!
    2 points
  15. @Robin S wow! @adrian thanks for your answer. I feel privileged to stand on the shoulders of all you coding giants. I am just a user who runs into stuff and here I am within a day this wonderful community makes things happen. What I am doing with my sites would not be possible without you coding giants. So processwire coding giants, hats off to all of you and a big heartfelt thanks. To all processwire coding giants: may your days be blessed with incredible coding insights that make things happen for all of your personal and business endeavors and may this result in joy and whatever results you wish for in your lives! THANKS!!!
    2 points
  16. Thanks @Robin S - looks like it is was much easier than I expected. I also added your request for a link to the module settings from the Process page. Really appreciate all the other tweaks and fixes - mucho appreciado! Thanks again!
    2 points
  17. Here is a new created version to track changes which works without any problems and you dont have to take care about the deletion of input values if the page was not saved successfully (like in the version before) Put this little piece of code inside your ready.php. //Compare before and after values and output a warning message $pages->addHookAfter('Pages::saveReady', function($event) { $page = $event->arguments('page'); $page->of(false); //configuration: change it to your needs $templates = ['event_businessvacations', 'event_dates', 'event_events', 'event_specialbusinesshours']; //array of templates where this hook should run $fields = ['summary', 'body']; //array of fields which should be checked //configuration end if(in_array($page->template->name, $templates)){ $changedfields = []; foreach($fields as $fieldname){ if ($page->isChanged($fieldname)) { // Page as it is in the DB $oldPage = wire('pages')->getById($page->id, array( 'cache' => false, // don't let it write to cache 'getFromCache' => false, // don't let it read from cache 'getOne' => true, // return a Page instead of a PageArray )); $changedfields[] = $oldPage->fields->$fieldname->label; } } $changedfields = implode(", ", $changedfields); if(!empty($changedfields)){ $this->warning(__("The following fields have been changed: {$changedfields}")); } } }); Change the configuration block to your needs (template names, field names). This little code snippet outputs only a warning message which fields have been changed - not more or less, but you can also run some other logics - its up to you. Note: Works also with repeaterfields, but you can only check the repeaterfields for changes in general. It is not possible to check for specific fields inside the repeater.
    2 points
  18. Are there already European developers implementing GDPR in their websites ? The European regulation will be obliged by 28/05/2018. What is it? https://www.eugdpr.org https://en.wikipedia.org/wiki/General_Data_Protection_Regulation It will be obliged to encrypt all personal data fields (name, email, phone, address, ... ) from users, and communicate about it. It would be interesting to implement an encryption setting for fields, just like the password field. That way all data in a database will be useless, unless you have a decryption key. I Think it's some stuff to think about, too meet the European regulation and to make Processwire even more secure.
    1 point
  19. As before, you can't easily modify ProcessPageList for this purpose. But you can use Lister (Pages > Find). So in your case you would filter according to some parent or some template, plus filter by "title starts with" some character. I have a module under development that will allow for a list/tree that dynamically changes the selector used by Lister. Not sure when it will be ready but that might end up being helpful for your scenario.
    1 point
  20. @theo - you can always take the opposite approach:
    1 point
  21. It seems it does and doesn't Basically any and all personal information, including something as simple as someone's name and email is a potential liability. So imagine you have a contact form, and just to be safe that form doesn't generate an email with all the info, but only a notification. You then log in to PW, see someone asking for an estimate, and how do you contact that person? Send an email and set a reminder to delete the Word document with the proposal and the email from the sent folder in case that person rejects the proposal or doesn't answer in 2 weeks? I'm seeing articles saying that internal emails are now a dangerous thing. Companies have to set up policies for managing information that safeguards it from a hacked email account, a stolen laptop or even a lost notebook. Imagine that, someone giving you their info over the phone, you write it down, the note gets lost and you're in court. Of course this is all hype aimed at getting Snapchat in the corporate world
    1 point
  22. I doubt it makes any difference if data is stored in an email inbox or on some webserver's database. The regulations apply to any data you store or process (storing and processing are clearly separated roles) if that's digital or analog or on post-its. To the contrary I'd even prefer the database in cases of form submits, because an email is easily forwarded to different people in a company and complying to a "request to be forgotten" can result in hunting down all the inboxes where submitted personal data are stored, while deleting a record in a db can be a lot easier.
    1 point
  23. https://cse.google.com/cse/publicurl?cx=014789015761400632609:fxrf0rj4wr4 FTW
    1 point
  24. Ok installed. thank you for the great help!!
    1 point
  25. Yes everything, PHP functions and also the ProcessWire API. Do not hesitate to install TracyDebugger to debug your app and speed up development
    1 point
  26. Yes this work! I learn now. I start to understand how use the hook! Thank you very much! I will try to do more complex hook. But I can use any php string functions ? like implode()
    1 point
  27. Hi @flydev, ahah no problem I can hear the whole story !! joke. Thank you for your starting point! If I have understand well this hook will add a new link inside the login from. exact? probably there are something I do wrong on hooks, I tried to do in inside the buildLoggedInLinks but it not work. Anyway make this hook it's bit hard for me at moment. I did not understand how hooks work, so, following the instructions in the hook page I have try to do some more easier hook, but not work, where I wrong ? (try to move the logout link next to the name) wire()->addHookAfter('LoginRegister::renderMessage', function ($event){ // $value contains the full rendered markup of a $page $value = $event->return; $value = str_replace( "<p class='LoginRegisterMessage'>" . $this->wire('sanitizer')->entities($message) . "<a href='$page->url?logout=1'>" . $this->_('Logout') . "</a></p>", $value); // set the modified value back to the return value $event->return = $value; });
    1 point
  28. Geil! Why the arrow icon when hovering the expanded mobile menu?
    1 point
  29. @adrian Cool ... ... but you will get unexpected results if the page has no title and uses the name instead or whatever. I would replace $p->title with $this->wire('processHeadline') to get it more stable. $this->addHookAfter('Page::render', function($event) { if($this->process != 'ProcessPageEdit') return; $p = $this->process->getPage(); $headline = "My ID is $p->id"; $event->return = str_replace($this->wire('processHeadline').'</h1>', '<strong><em>'.$headline.'</em></strong></h1>', $event->return); }); @flydev $this->getUpdateStatus() // ? what's that? return?
    1 point
  30. Hey @kixe thanks for this idea, I tried to implement it but I ran into an issue. I can't manage to set a different label depending on a condition. I think I must be missing something. The hook : $this->wire->addHookAfter('ProcessPageListRender::getPageLabel', $this, 'getPageLabel'); public function getPageLabel($event) { $listedPage = $event->arguments[0]; if($listedPage->template->name == 'tpl1' || $listedPage->template->name == 'tpl2') { $this->status = $this->getUpdateStatus(); foreach ($this->status as $key => $value) { $event->return = ($this->status[$key]['closing'] == -1 || $this->status[$key]['transactions'] == -1) ? '<span class="uk-label label-update-status-error">ERR</span> ' : '<span class="uk-label label-update-status-ok">OK</span> '; } } } Each page on the page-tree have the same label label-update-status-ok : Could you share a portion of code ? ? @theo sorry for hijacking your thread ? Edit: fixed, it was just bad logic in the foreach loop inside the hook. Thanks again @kixe it rocks !
    1 point
  31. Thanks for the help @kixe and @kongondo I got it working with a small change. It only works when add the name of the template to the selector. <?php $mostRecentPage = $pages->get("created_users_id=$user->id, sort=-created, template=places");?> Luckily in this project, my clients only create pages based on this template.
    1 point
  32. @OllieMackJames and others - @Robin S was kind enough to enhance AdminActions to support RepeaterMatrix fields:
    1 point
  33. $firstItem = $feature->issue->first(); echo "<p class='iss uk-text-tiny bold caps'><a href='$firstItem->url'>$firstItem->title</a></p>";
    1 point
  34. Sure ! ? To get you started, I hope I am not spoiling things, you can add a link quite easily. In the file ready.php put : wire()->addHookAfter('LoginRegister::buildLoginForm', function ($event) { $obj = $event->object; $form = $event->return; $f = new InputfieldMarkup(); $f->markupText = "<a href='". wire('pages')->get('/purchased-products/')->url ."'><h3>Purchased Products</h3></a>"; foreach ($form->children as $field) { if ($field instanceof InputfieldSubmit) { // find the submit button $form->insertAfter($f, $field); // insert the InputfieldMarkup after the button } } $event->return = $form; });
    1 point
  35. Hi @OllieMackJames - I'm afraid I don't have the time to do this at the moment, but I am sure you can extend the "Copy Repeater Items to Other Page" action to support RepeaterMatrix fields - probably just a matter of another loop. If you make those changes, I'd really appreciate a PR Let me know if you have any questions.
    1 point
  36. Hi @elabx I did not know this property, I will make an option available for that. I plan to add new features and test the module in the next 10 days, sorry I miss time ?
    1 point
  37. This is probably because cookie handling is supposed to be regulared by the eprivacy law, which will be obliged at the same time as the gdpr, but is a separate regulation. Sadly this one still doesn't seem to be finalized and it's getting far less attention.
    1 point
  38. For such a site it must be taken seriously as GDPR tries to differentiate the "level of security measures and the fine to pay in the absence of proper compliance" – so to speak –, meaning that security measures applied to data collection and handling must align with the amount of data and its sensitivity. I guess your client will need a "GDPR professional" to make it right. The websites I deal with require less work to comply but it is sill something what will add up to lots of ours of work on my end.
    1 point
  39. GDPR itself is mandatory, but there was a confusion about storing personal data in an encrypted way only as it was supposed to be necessary to comply. Being a European developer, I will spend a considerable amount of time to help my clients out with GDPR and I'm still learning the details... However, this encryption issue seemed to be a huge technical problem if it is mandatory. Since it is not, now I can concentrate on the other issues GDPR generates. I think this confusion about encryption was the biggest issue so I though I would post some links to show that is in a non-issue after all. There are good resources about GDPR about there, but here is a brief introduction to check out first: http://ec.europa.eu/justice/smedataprotect/index_en.htm Also note that: "Where does GDPR apply? If you sell any products to customers based in the EU, or have EU visitors to your site, you’ll need to make sure your site complies with GDPR. It applies to all 28 EU member states and to entities and organisations outside the EU when processing the data of citizens within it. IMPORTANT to note: Google Analytics and others ARE personal data collectors too! Eg: Statistics apps like cPanel apps, similar CMS plugins, custom solutions like Piwik", etc. And this means not European websites should also consider complying to avoid yet to be seen possible legal issues. The good thing is that the silly automatic cookie consent does not seem to apply anymore, as setting cookies is not data collection in itself. In GDPR there is only one sentence where cookies are mentioned: https://gdpr-info.eu/recitals/no-30/ And it is just about listing a few technical possibilities of possible personal profile building. However, if there is no profile building – meaning there is no data collection this way – then cookies are non-issues. I still need to read up on this one, but this is my current understanding. Of course, if cookies are used for profiling then it is a different story and they must be considered when dealing with GDPR. There is a lot to consider regarding GDPR. As you can imagine, complying is a time consuming process, a real PITA
    1 point
  40. How can GDPR not be mandatory yet still have the right to impose huge fines for non-compliance? Interested to know how this impacts storing user profile information in the PW db and/or front-end user form data saved to the DB (eg FormBuilder entry and to-page options). Your thoughts?
    1 point
  41. Hi @teppo, thank you. It works. However, I had to edit and re-save the page.
    1 point
  42. Actually, you probably want $field->addFlag(Field::flagAutojoin); $field->save(); so you don't remove any other existing flags.
    1 point
  43. Hi and welcome! Advice: Definitely stay in the admin! I had exactly the same thoughts before I created my CRM because modifying the admin seemed totally complex and out of my scope. But once you get the concept it is REALLY simple and you get all the benefits that the pw backend offers (all fields, all functionality like login, sanitization, field collapsing, hooks etc). That's why I created the blogpost that Robin linked to (thx btw ). The ROI (return on invest) of digging into the PW admin is huge and it will help you a lot to improve all your pw related work, because you will understand everything a lot better. I wish you good luck and a lot of fun
    1 point
  44. @ngrmm Your solution looks good, since the mod operator is the fastest way to determine even/ odd in PHP, but I would loop only once. $even = ''; $odd = ''; foreach ($allPages as $k => $v) { if ($k % 2) { $even .= "<div>$v->title</div>"; } else { $odd .= "<div>$v->title</div>"; } } echo "<div class='items'>"; echo "<div class='odd'>"; echo $odd; echo "</div>"; echo "<div class='even'>"; echo $even; echo "</div>"; echo "</div>";
    1 point
  45. I think this is totally justified. The amount of data that is being stolen these days is just crazy, and it has real impacts on real people. One of the worst incidents to date is the Equifax hack: https://en.wikipedia.org/wiki/Equifax#May.E2.80.93July_2017_data_breach John Oliver did a good piece on it: Automatic encryption just has to become the new normal, and I'm confident it won't be that big a deal to implement once the code wizards out there turn their minds to the challenge.
    1 point
  46. Hi @Nurguly Ashyrov, this looks like a great module - thank you for developing it! I'm a complete noob to the world of GraphQL, and have been trying for two days to get this module running in combination with Ember.js. If I could get it to work, it sure would be a glorious combination. But so far it has been pretty frustrating One thing that I keep running into, is that your implementation always returns an array of pages, using the 'list' field* inside the query. However, this makes it impossible to request a single page. Even when using something like limit=1 in the selector. For instance, I could imagine this to work fine { basic_page(s: "name:contact") { first { id name } } } Which then could return { "data": { "basic_page": { "first": { "id": "1017", "name": "contact" } } } } Basically, any of PW's regular PageArray methods to find something would be a welcome addition ( ie. ->eq(n), ->get(selector), ->first(), ->last(), etc.) Is this something I can achieve with the getQuery hook? Or in another way? Thanks in advance for any pointers or help. (* I have to say, this use of the field keyword is very confusing for a long time PW user).
    1 point
  47. Update: working with this setup for a few months, I had quite a few permission related issues which were frustrating. So I decided to do some more research on existing docker projects that are well maintained and bring the features I need. Finally I found http://laradock.io/. I've been using it for 3 months now and I am really happy with it. Very flexible and well maintained set of docker containers. I'm totally happy and can recommend it to devs who are interested in this topic.
    1 point
  48. Hi @mvdesign. So sorry that I could not respond earlier. I decided to make an introduction video for this module to help people that are trying to use it. But then, I never made a screencast video before, and on top of that, the last time I spoke english was 2011. So I had to take dozens of try-outs till I got something watchable. So here is the video. It shows how you would create/update pages with this module. The video is far from OK, so I will probably record another one after I get some feedback. Until then please refer to this video to learn about how the module works.
    1 point
×
×
  • Create New...