Leaderboard
Popular Content
Showing content with the highest reputation on 09/10/2019 in all areas
-
I'm using this: https://github.com/dragan1700/site-backup One script creates a ZIP of the entire site, the other creates a DB-dump. They can be also used with Cron, if you just put in the shebang (may vary in your server setup). Since normally I'm not working with huge databases, I didn't do an option to zip the .sql as well, but I might add that later if the need arises.3 points
-
See here: https://github.com/BernhardBaumrock/tabulator.test/blob/837d509f1ef6816fe3629c163bd66d53c5e39209/site/ready.php#L31-L73 That's exactly doing what you are looking for but also creates a ZIP of the sql (which reduces size drastically). It also comes with a restore script: https://github.com/BernhardBaumrock/tabulator.test/blob/master/site/assets/mysqldump/restore.php This is the first time I'm using it, so it's not well tested and some parts are hardcoded (eg tabulator.sql / tabulator.zip). But it should get you going. I created this because the pw internal dump takes ages to restore ( for @dragan it took several hours? ). My workflow: logout commit changes push changes3 points
-
The problem is in ProcessPageAdd on line 1021: https://github.com/processwire/processwire/blob/649d2569abc10bac43e98ca98db474dd3d6603ca/wire/modules/Process/ProcessPageAdd/ProcessPageAdd.module#L1021 It is calling Page::setEditor, which is overridden by User::setEditor, which performs a redirect instead of actually setting the editor. Removing this line fixes the issue. Github issue: https://github.com/processwire/processwire-issues/issues/9773 points
-
Mystique Module for ProcessWire CMS/CMF Github repo : https://github.com/trk/Mystique Mystique module allow you to create dynamic fields and store dynamic fields data on database by using a config file. Requirements ProcessWire 3.0 or newer PHP 7.0 or newer FieldtypeMystique InputfieldMystique Installation Install the module from the modules directory: Via Composer: composer require trk/mystique Via git clone: cd your-processwire-project-folder/ cd site/modules/ git clone https://github.com/trk/Mystique.git Module in live reaction with your Mystique config file This mean if you remove a field from your config file, field will be removed from edit screen. As you see on youtube video. Using Mystique with your module or use different configs path, autoload need to be true for modules Default configs path is site/templates/configs/, and your config file name need to start with Mystique. and need to end with .php extension. Adding custom path not supporting anymore ! // Add your custom path inside your module class`init` function, didn't tested outside public function init() { $path = __DIR__ . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR; Mystique::add($path); } Mystique module will search site/modules/**/configs/Mystique.*.php and site/templates/Mystique.*.php paths for Mystique config files. All config files need to return a PHP ARRAY like examples. Usage almost same with ProcessWire Inputfield Api, only difference is set and showIf usage like on example. <?php namespace ProcessWire; /** * Resource : testing-mystique */ return [ 'title' => __('Testing Mystique'), 'fields' => [ 'text_field' => [ 'label' => __('You can use short named types'), 'description' => __('In file showIf working like example'), 'notes' => __('Also you can use $input->set() method'), 'type' => 'text', 'showIf' => [ 'another_text' => "=''" ], 'set' => [ 'showCount' => InputfieldText::showCountChars, 'maxlength' => 255 ], 'attr' => [ 'attr-foo' => 'bar', 'attr-bar' => 'foo' ] ], 'another_text' => [ 'label' => __('Another text field (default type is text)') ] ] ]; Example: site/templates/configs/Mystique.seo-fields.php <?php namespace ProcessWire; /** * Resource : seo-fields */ return [ 'title' => __('Seo fields'), 'fields' => [ 'window_title' => [ 'label' => __('Window title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'attr' => [ 'placeholder' => __('Enter a window title') ] ], 'navigation_title' => [ 'label' => __('Navigation title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'showIf' => [ 'window_title' => "!=''" ], 'attr' => [ 'placeholder' => __('Enter a navigation title') ] ], 'description' => [ 'label' => __('Description for search engines'), 'type' => Mystique::TEXTAREA, 'useLanguages' => true ], 'page_tpye' => [ 'label' => __('Type'), 'type' => Mystique::SELECT, 'options' => [ 'basic' => __('Basic page'), 'gallery' => __('Gallery'), 'blog' => __('Blog') ] ], 'show_on_nav' => [ 'label' => __('Display this page on navigation'), 'type' => Mystique::CHECKBOX ] ] ]; Searching data on Mystique field is limited. Because, Mystique saving data to database in json format. When you make search for Mystique field, operator not important. Operator will be changed with %= operator. Search example $navigationPages = pages()->find('my_mystique_field.show_on_nav=1'); $navigationPages = pages()->find('my_mystique_field.page_tpye=gallery');2 points
-
The machine exists, but as an addicted DistroHopper, it's been wiped. Client? I use the command line. No worries amigo, I have accepted the loss and will restart the project again tomorrow ? LESSON LEARNED!2 points
-
Hello, I'm getting out of web design and development and I'm looking to get hold of an AU-based PW developer to send some clients to. I'm not looking to overseas developers at all. You can DM me here. Cheers Marty1 point
-
Well, I had it for ages, but only today made a Github repo and thought I could just as well share it. And yes, it's similar because we apparently use the same core class ifsnop :-) It's especially useful if you have to work on a site where you can't quickly create a files-backup as ZIP, nor un-zip easily via control panel (which is standard in Plesk et al). Or if you can't run system commands, because the hosting company doesn't allow it. On some sites, I have it running with a hook and/or PW lazycron. And before any major changes (dev/prod), I just trigger it manually.1 point
-
Edit: I misunderstood the question above...this post is not really relevant but I'll leave it here anyway :-). This is how I close PW modals (in Media Manager and other modules). /** * Close jQuery UI Modal. * * @param integer $s Number of milliseconds before closing modal. * */ function closeDialog($s = 1000) { setTimeout(function() { jQuery('iframe.ui-dialog-content').dialog('close'); }, $s); } // call the function // if adding media into a Media Manager Inputfield and closing the dialog is set // in this case data is an Ajax Response if (action === "insert" && data.insertAndClose) closeDialog(); Question, are pw-panels the same as pw modals?1 point
-
My website stores user's info after they join such as username, password, email, IP and I added also a checkbox for the "privacy accepted" status and another one with the info about the version of the privacy policy at that time but from what I read storing these data in the database is not enough.1 point
-
@OrganizedFellow Do think about backing up your drive now. If it's starting to fail, this could be an early warning for you.1 point
-
Hi @Mike Rockett – I'm back with the endless requests ? How do you feel about supporting WireCache in MarkupSitemap, possibly as an alternative to (if not instead) MarkupCache? The thing is that due to hosting-related reasons caching in the database would be easier for me, while current MarkupCache implementation is slightly problematic. I could send you a PR (or merge request, as you're using GitLab) in case you're interested.1 point
-
Added a new example how to add and hide columns via JS:1 point
-
I think that's the best solution and I can't think of any problems using it ?1 point
-
Hi @Hardoman I post you a code example below that works for me since ages and also with recent PW versions. It includes watermarking too! It is called in a custom module and the event is >before "InputfieldFile::fileAdded" <, but you can call it in ready.php too. Hopefully it is of help for you. Otherwise please ask further. :) public function importImage($event) { $inputfield = $event->object; // handle to the image field if(!$inputfield instanceof InputfieldImage) { // we need an images field, not a file field return; // early return } if(version_compare(wire('config')->version, '2.8.0', '<')) { $p = $inputfield->value['page']; // get the page, PW < 2.8 } else { $p = $inputfield->attributes['value']->page; // get the page, PW >= 2.8 | 3.0 (or only from 3.0.17+ ??) } if('images' != $inputfield->name) return; // we assume a field with name: images if('album' != $p->template) return; // don't do it on other pages than archive album $image = $event->argumentsByName('pagefile'); // get the image // prebuild variations // AdminThumb $image->height(260); // AlbumThumbnail $portrait = $image->height > $image->width; $w = 228; if($portrait) { $w1 = intval($w); $h1 = intval(($w1 / 3 * 4) + 38); } else { $w1 = intval($w); $h1 = intval(($w1 / 3 * 2)); } $image->crop("width=$w1, height=$h1"); // Slick-Slideshow $wmPng = $this->pages->get('id=13967')->getUnformatted('watermark')->first()->width(403); // sharpening added, quality from 80 to 90 $master = $image->contain('width=1000, height=700, quality=100, sharpening=none'); $master = $master->pim2Load('full', false)->watermarkLogo($wmPng)->setQuality(100)->setUpscaling(true)->setSharpening('none')->pimSave(); $sizeArray = array(array(448, 336), array(678, 506), array(908, 676)); foreach($sizeArray as $sizes) { $master->size($sizes[0], $sizes[1], array('upscaling'=>false, 'cropping'=>false, 'quality'=>90, 'sharpening'=>'soft')); } // sharpening added, quality from 80 to 90 // prebuild variations // check / import IPTC data $additionalInfo = array(); $info = @getimagesize($image->filename, $additionalInfo); if($info !== false && is_array($additionalInfo) && isset($additionalInfo['APP13'])) { $iptc = iptcparse($additionalInfo["APP13"]); if(is_array($iptc) && isset($iptc["2#025"]) && is_array($iptc["2#025"]) && count($iptc["2#025"])>0) { $tmp = $iptc["2#025"]; $tags = array(); foreach($tmp as $k=>$v) { if(empty($v)) continue; $tags[] = jhpTextConversion(trim(strtolower($v))); } $p->images->trackChange('tags'); // prepare page to keep track for changes $image->tags = implode(', ', $tags); $p->save('images'); // save the page } } // check / import IPTC data }1 point
-
I'm no expert either but there seems to be a consensus that GDPR does not require a one-fits-all approach for everything but quite the contrary. For example on a simple PW site where cookies are only used for their default purposes by the system and only editors and superusers login, I usually just state some "required for security purposes" blah-blah on the Imprint page linked form the footer or even form the main menu, and that is all there is to it. What you should do depends on lots of factors, including the local law. That's the "beauty" of regulations like this...1 point
-
What exact consent do you want to save/document/store? Cookie banner? Newsletter signup/opt-in/double-opt-in? Marketing / Re-Targeting opt-in? I'm not a lawyer by any means so I don't want you to follow my approach but this is the way I do it and my legal advisors don't scream in total panic when I tell them about it. Cookie banner Client side cookie (simple true/false) if true: cookies were set and the banner doesn't pop up again if false: no cookies at all (besides session cookies) cookie banner pops up every time Newsletter most of the time I use Mailchimp as I have a GDPR/DPA contract with them to handle everything - they store and document all opt-ins and opt-outs and are responsible for it. Users have to tick up to two checkboxes in order to signup for the newsletter - the first a common privacy checkbox, the second is a detailed explanation that the newsletter is handled by a third party. I will receive a sign-up notification via email I can archive, print or whatever. Related database entries will be deleted a few days later. Mailchimp uses double-opt-in in all cases and documents these. Unconfirmed signups will be deleted once a week. Marketing / Re-Targeting I stopped using it as my marketing budget isn't that high to pay even more lawyers. ?1 point
-
1 point
-
I use an IDE and found it stressful to have to work-around deploying config.php This is how I found your thread. Thank you! I integrated your solution into my own workflow and came up with this to share back here: /site/config.php (like @bernhard except last line) // include config file from outside of the repo $client = 'config-' . end(explode('/',__FILE__, -2)); include("../$client.php"); The PHP end() function and the minus 2 in the explode(), always gets the URI domain base. (As long as PW keeps it there.) Since my usual deployment flow is from ABC.dev -> test.mybox.com/ABC -> ABC.com ...in my root folder, safely out of reach (like @bernhard's concept), I then create 3 files each containing config deployment differences. ../config-ABC.dev.php and ../config-ABC.php and ../config-ABC.com.php For those also using PHPStorm, since these files are located out of project, I would add them in Favorites. (And add it's root folders in Deployment Mappings). I can then easily make use of IDE features like "Compare Two Files", "Sync with Deployed to", etc. Removing doubts about what config property I may have missed across the board. No more stress.1 point
-
1 point
-
@Zeka There is many inconsistencies between in-memory and DB. Things being case sensitive etc. I'm recently seeing the inconsistency throw people more and more. As the API is the same - I think it's hard to know what's going to be DB and what's going to be in-memory. I think there are things that can be done to bring in-memory searches to bring it inline with DB searches. For now this should work: <?php $validation = []; preg_match_all('/\(([^\)]+)\)/' $selector, $matches); foreach($matches[1] as $match) { $validation[] = $page->matches($match); } if(in_array(true, $validation)) { // Page Matches one OR Group. } ?> I haven't tested it, but it should work, might require a little tweaking. Or <?php $validation = false; preg_match_all('/\(([^\)]+)\)/' $selector, $matches); foreach($matches[1] as $match) { if(!$validation) { $validation = $page->matches($match); } } if($validation) { // Page Matches one OR Group. } ?>1 point
-
It's in the selectors docs (admittedly, in the fine print at the bottom of the relevant section):1 point
-
1 point
-
There is very little difference: http://processwire.com/api/ref/wire-data/set/ This one sets the property value directly. The $key is converted to a string (e.g. $this->myString = 'my value';) $this->$key = $value; This one uses the method set() to set both a key and a value for you. I'm not sure if the $key is manipulated in anyway behind the scenes, e.g make it 'property' friendly. I've had a quick look and couldn't find anything to that effect. $this->set($key, value); You can also do (Set a property using array access) : $this[$key] = $value; Edit: Reading your thread title, there is no right way. All ways are correct and are documented ?1 point