LostKobrakai Posted July 13, 2017 Author Share Posted July 13, 2017 Yesterday I released 0.3.1 with the access migrations like described here: It does also include a fix to allow usage in multisite setups using $config->paths->site instead of hardcoding /site/…. 2 Link to comment Share on other sites More sharing options...
ZGD Posted October 2, 2017 Share Posted October 2, 2017 I'm making extensive use of migrations for a project and had a question regarding writing migrations for matrix fields. When creating a new FieldtypeRepeaterMatrix field, I usually need to create two migrations. The first actually creates the blank matrix field, and then the second populates it with types/fields. This is because the template associated with the matrix is not actually created when the initial save() method is called when creating the field. Does anyone know if it is possible to force PW to create this template via the API? Wanted to also say how useful this module is. Would love to see migrations built into the core one day as it's totally changed how we use PW. I've been thinking about submitting a pull request with some new migration classes I've been building, would be great to have some reusable templates for complex situations like this. EDIT: I just realized I could probably just create the template as I would any other template on the initial field setup. But if there is an alternative save() method that would let PW handle the template creation that would still seem easier! 2 Link to comment Share on other sites More sharing options...
ZGD Posted October 3, 2017 Share Posted October 3, 2017 Replying to myself here in case anyone else was looking for a similar migration. This seems to work for setting up repeater fields via a single migration file. Not sure if the method I've used for generating the repeater template is sensible but it will do for now: <?php class Migration_2017_10_01_10_10_10 extends FieldMigration { public static $description = "<b>+FIELD</b> Custom Matrix (custom_matrix)"; protected function getFieldName(){ return 'custom_matrix'; } protected function getFieldType(){ return 'FieldtypeRepeaterMatrix'; } protected function getMatrixTemplateName() { return FieldtypeRepeater::templateNamePrefix . $this->getFieldName(); } protected function getMatrixTypes() { return [ [ 'name' => 'foo', 'label' => 'Foo', 'head' => '{matrix_label}', 'fields' => [ 'title' => [ 'label' => 'Title (Optional)', 'required' => 0, ], 'markdown', ], ], [ 'name' => 'bar', 'label' => 'Bar', 'head' => '{matrix_label}', 'fields' => [ 'title' => [ 'label' => 'Title (Required)', 'required' => 0, ], 'image', ], ], ]; } protected function addFieldToRepeaterList($matrixField, $field) { $repeaterFields = $matrixField->repeaterFields; if (!is_array($repeaterFields)) $repeaterFields = []; if (!in_array($field->id, $repeaterFields)) { $repeaterFields[] = $field->id; } $matrixField->repeaterFields = $repeaterFields; } protected function addMatrixType($matrixField, $index, $config) { $templateName = $this->getMatrixTemplateName(); $prefix = 'matrix' . ($index + 1) . '_'; $matrixField[$prefix.'name'] = $config['name']; $matrixField[$prefix.'label'] = $config['label']; $matrixField[$prefix.'head'] = $config['head']; $matrixField[$prefix.'sort'] = $index; $fields = []; foreach ($config['fields'] as $key => $property) { $field = (!is_numeric($key)) ? $this->fields->get($key) : $this->fields->get($property); $fields[] = $field->id; $this->addFieldToRepeaterList($matrixField, $field); $this->insertIntoTemplate($templateName, $field); if (!is_numeric($key)) { $this->editInTemplateContext($templateName, $field, function(Field $f) use ($property) { foreach ($property as $prop => $val) { $f->$prop = $val; } }); } } $matrixField[$prefix.'fields'] = $fields; } protected function fieldSetup(Field $f){ $f->label = 'Custom Matrix'; $f->tags = 'matrix'; $f->required = 1; $f->icon = 'fa-bars'; // Do this to generate a template file for the repeater // @TODO Find a better way to do this $fieldtype = $f->type; $numOldReady = $fieldtype->countOldReadyPages($f); // Setup matrix stuff $matrixTypes = $this->getMatrixTypes(); foreach ($matrixTypes as $i => $matrixData) { $this->addMatrixType($f, $i, $matrixData); } // Insert into template $template = 'my-template'; $this->insertIntoTemplate($template, $f); } } 1 Link to comment Share on other sites More sharing options...
elabx Posted October 23, 2017 Share Posted October 23, 2017 Was about to ask about FiledtypeTable migrations but decided to try myself and it seems to work fine this way, dropping it here in case someone's in need: <?php class Migration_2017_10_23_12_24_20 extends FieldMigration { public static $description = "Add table field"; protected function getFieldName(){ return 'booking_advanced_fields'; } protected function getFieldType(){ return 'Table'; } protected function fieldSetup(Field $f){ $f->label = 'Booking Form Extra Fields'; $f->collapsed = Inputfield::collapsedNever; $this->insertIntoTemplate('home', $f, "booking_advanced", true); //Booking advanced is a checkbox in this case, hence the showIf setup to make the table appear if required $this->editInTemplateContext('home', $f, function(Field $f) { $f->set("showIf","booking_advanced=1"); }); $f->set("maxCols", 4); $f->set("col1name", "column1"); $f->set("maxCols", 4); $f->set("col1type", "text"); $f->set("col1sort", "1"); $f->set("col1label", "Column 1 Label"); $f->set("col1width", 50); $f->set("col1settings", "textformatters=TextformatterEntities\nplaceholder=\ndefault=\nmaxLength=2048" ); $f->set("col2name", "column2"); $f->set("col2type", "text"); $f->set("col2sort", "2"); $f->set("col2label", "Column 2 Label"); $f->set("col2width", 50); $f->set("col2settings", "textformatters=TextformatterEntities\nplaceholder=\ndefault=\nmaxLength=2048" ); $f->save(); $table_module = wire("modules")->get("FieldtypeTable"); $table_module->_checkSchema($f, true); } } 2 Link to comment Share on other sites More sharing options...
simonsays Posted May 2, 2018 Share Posted May 2, 2018 (edited) Hello! Thanks for the wonderful module! Does anyone know, how to use it for FieldtypeOptions? Like picking the type (single or multiple) and setting options values. My attempts for this have failed so far. @LostKobrakai Edited May 2, 2018 by simonsays Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 2, 2018 Author Share Posted May 2, 2018 @simonsays Something like that: class Migration_xxxx_xx_xx_xx_xx_xx extends FieldMigration { public static $description = "Create field"; protected function getFieldName(){ return 'field_name'; } protected function getFieldType(){ return 'FieldtypeOptions'; } protected function fieldSetup(Field $f){ $f->label = 'Label'; $f->inputfieldClass = 'InputfieldRadios'; $options = <<< _END 34 36 38 40 42 44 46 48 _END; $f->type->manager->setOptionsString($f, $options, true); } } 2 Link to comment Share on other sites More sharing options...
simonsays Posted May 2, 2018 Share Posted May 2, 2018 1 hour ago, LostKobrakai said: @simonsays Something like that: class Migration_xxxx_xx_xx_xx_xx_xx extends FieldMigration { public static $description = "Create field"; protected function getFieldName(){ return 'field_name'; } protected function getFieldType(){ return 'FieldtypeOptions'; } protected function fieldSetup(Field $f){ $f->label = 'Label'; $f->inputfieldClass = 'InputfieldRadios'; $options = <<< _END 34 36 38 40 42 44 46 48 _END; $f->type->manager->setOptionsString($f, $options, true); } } Awesome, thanks @LostKobrakai! Saved me a lot of effort and I also became slightly smarter in the process ;) Link to comment Share on other sites More sharing options...
simonsays Posted May 14, 2018 Share Posted May 14, 2018 (edited) @LostKobrakai When I try to install module using your migration, extra permission declared for this module in getModuleInfo() is not installed automatically. When I install module via admin, permission is added OK. Is this a bug? Or was it done like that intentionally? Edited May 14, 2018 by simonsays Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 14, 2018 Author Share Posted May 14, 2018 It's certainly not intentional. https://github.com/LostKobrakai/Migrations/blob/master/classes/ModuleMigration.php There's what a module migration does. I'd expect that $this->modules->install($name) would also take care about installing any permissions of modules. — I just quickly checked the source and it seems this method should handle that. 2 Link to comment Share on other sites More sharing options...
simonsays Posted May 18, 2018 Share Posted May 18, 2018 On 5/14/2018 at 5:57 PM, LostKobrakai said: It's certainly not intentional. https://github.com/LostKobrakai/Migrations/blob/master/classes/ModuleMigration.php There's what a module migration does. I'd expect that $this->modules->install($name) would also take care about installing any permissions of modules. — I just quickly checked the source and it seems this method should handle that. Weird, failed first 2 times, but works perfectly now. Logs did not find anything. Guess, something with my localhost... Link to comment Share on other sites More sharing options...
simonsays Posted May 22, 2018 Share Posted May 22, 2018 @LostKobrakai Do you happen to have a good example of adding a repeater field (just the field, no data)? Found this old thread, which introduces a fairly complex approach, but it is rather old, so I was hoping, that something has changed over the last 4 years. Looked through FieldtypeRepeater module, but did not find any helpful methods. Link to comment Share on other sites More sharing options...
simonsays Posted November 29, 2018 Share Posted November 29, 2018 (edited) @LostKobrakai I have this code for repeater migration, however, I noticed something. Not sure if it is a bug or the way it should be. <?php class Migration_2018_11_18_00_00_00_RepeaterAccordionField extends FieldMigration { public static $description = "Add repeater for accordion"; protected function getFieldName() { return 'repeater_accordion'; } protected function getFieldType() { return 'FieldtypeRepeater'; } protected function fieldSetup(Field $f) { $f->label = 'Repeater accordion'; $f->collapsed = Inputfield::collapsedNever; $repeaterFieldGroup = new Fieldgroup(); $repeaterFieldGroup->name = 'repeater_' . $this->getFieldName(); //Add fields to fieldgroup - add others as necessary $repeaterFieldGroup->append($this->fields->get('title')); $repeaterFieldGroup->append($this->fields->get('content_columns')); $repeaterFieldGroup->save(); $repeaterTemplate = new Template(); $repeaterTemplate->name = 'repeater_' . $this->getFieldName(); $repeaterTemplate->flags = 8; $repeaterTemplate->noChildren = 1; $repeaterTemplate->noParents = 1; $repeaterTemplate->noGlobal = 1; $repeaterTemplate->slashUrls = 1; $repeaterTemplate->fieldgroup = $repeaterFieldGroup; $repeaterTemplate->save(); $repeaterPage = "for-field-{$f->id}"; $f->parent_id = $this->pages->get("name=$repeaterPage")->id; $f->template_id = $repeaterTemplate->id; $f->repeaterReadyItems = 3; //Add fields to the repeater - add others as necessary $f->repeaterFields = $this->fields->get('title'); $f->repeaterFields = $this->fields->get('content_columns'); $f->save(); } } If I rollback the migration, it deletes the field. But does not affect the fieldgroup. So, when I try to run the migration for the second time - it throws me an integrity violation error (originates from fieldgroups table). Is this the expected behaviour? Edited November 29, 2018 by simonsays specify Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 29, 2018 Author Share Posted November 29, 2018 You can look into the FieldMigration class to see what it does on migration/rollback. It should just remove the field itself. If that doesn‘t clean up the fieldgroup than it‘s expected behaviour. You can still override/add to that by putting your own upgrade/downgrade functions like e.g. I did it here: https://github.com/LostKobrakai/MigrationSnippets/blob/master/Reverse_Template_Migration_Type.php Link to comment Share on other sites More sharing options...
simonsays Posted November 30, 2018 Share Posted November 30, 2018 16 hours ago, LostKobrakai said: You can look into the FieldMigration class to see what it does on migration/rollback. It should just remove the field itself. If that doesn‘t clean up the fieldgroup than it‘s expected behaviour. You can still override/add to that by putting your own upgrade/downgrade functions like e.g. I did it here: https://github.com/LostKobrakai/MigrationSnippets/blob/master/Reverse_Template_Migration_Type.php It was just a quick question to confirm, whether repeater field downgrade works out of the box or requires additional extending. Thanks for the reply. Link to comment Share on other sites More sharing options...
rastographics Posted January 18, 2019 Share Posted January 18, 2019 @LostKobrakai Sorry for noob question, but after installing Migrations module and creating my first migration, my IDE gives an error because the variable $this is unexpected... It seems like no one else has encounter this...is something wrong with my pw setup? Any hints on where I can look for answers? Link to comment Share on other sites More sharing options...
teppo Posted January 18, 2019 Share Posted January 18, 2019 @rastographics, it looks like you're missing a semicolon (";") at the end of the line starting with "$f->description". Or was the screenshot cut off early? ? 1 Link to comment Share on other sites More sharing options...
rastographics Posted January 18, 2019 Share Posted January 18, 2019 @teppo AAH! I can't believe I wasted so much time looking into namespaces and scope context yesterday!!! How embarrassing. Thank you. 2 Link to comment Share on other sites More sharing options...
LostKobrakai Posted May 20, 2020 Author Share Posted May 20, 2020 As hinted in the topic on RockMigrations I'll deprecate my module in favor of it. I've added noted to github and this topic: Quote 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. Link to comment Share on other sites More sharing options...
LostKobrakai Posted June 22, 2020 Author Share Posted June 22, 2020 I've heard from a few people in the last weeks, which seemed not to happy about by decision in regards to this module and especially the suggestion of RockMigrations as an alternative. Therefore I'll leave a few more thought. The module has been in it's current state for years. The last commit from my side was from Juli 2017. Just like the module continued to work till today it'll likely do in the future. There might be things to change with new PHP versions or PW versions – but maintaining working condition should be a fairly simple job. Given that I don't have any active projects anymore using the module (to the most part even for processwire in general) I personally can't and won't deal with keeping the module maintained. My suggestion for supporting RockMigration was mostly based on the fact that it's way more actively maintained and I feel it's better to group efforts behind a single project – especially given the processwire community being on the smaller end – but if RockMigration doesn't work for someone and this module does, feel free to use it. I'd be happy for anyone to pick this up and maintain it going forward, it just won't be me. /cc @Sascha Nos @elabx 4 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now