Jump to content

RockMigrations 🚀🚀 The Ultimate Automation and Deployment-Tool for ProcessWire


bernhard
 Share

Recommended Posts

1 minute ago, zoeck said:

I'm still using v1 of RockMigrations, but i think it's time to switch to the new version ? 

Definitely ? There are some methods in v1 that are not (yet) in v2 - so if you find one that we need in v2 let me know. Though one reason for the switch was to get rid of many old concepts/methods that I did not use any more. And also to streamline debugging and error messages.

In v1 some methods threw an error if something went wrong, others returned silently. In v2 this is streamlined and every method has a second parameter to make it return silently if that is what you want (eg when deleting a previously added field which would work on the first run of the migration but on all following would throw a log "field xx not found").

Link to comment
Share on other sites

1 hour ago, bernhard said:

Thx @MateThemes it's fixed in v1.6.8

PS: Why is RockMigrations placed in the "MagicPages" folder? Shouldn't that be "RockMigrations"??

Hy @bernhard

You are right. I just downloaded the RockFrontend and RockMigrations and installed it via the backend as zip upload. I need to say, I just don't know why this happened?! Is it better to move the module inside the side modules folder and add the module from there?

Thank you.

Link to comment
Share on other sites

2 minutes ago, MateThemes said:

Hy @bernhard

You are right. I just downloaded the RockFrontend and RockMigrations and installed it via the backend as zip upload. I need to say, I just don't know why this happened?! Is it better to move the module inside the side modules folder and add the module from there?

Thank you.

I removed the module from the folder and installed it with uploading RockMigrations in site/modules now the error message is gone.

It seems to happen with the zip upload.

Link to comment
Share on other sites

I tried an update from v1 to v2 today

But now Tracy shows me these errors on every page ? (including admin)

496659020_2022-09-2014_16_32-RockMigrations.png.ba84247af1006143572c318d5f0fea88.png

When I uninstall the module, the error is gone again.
Im using the current PW master version (3.0.200)

Link to comment
Share on other sites

@bernhard This is the function in the module file:

<?php
  /**
   * Get changed watchfiles
   * @return array
   */
  public function getChangedFiles()
  {
    $changed = [];
    foreach ($this->watchlist as $file) {
      // remove the hash from file path
      // hashes are needed for multiple callbacks living on the same file
      $path = explode(":", $file->path)[0];
      $m = filemtime($path);  /////////// LINE 1282
      if ($m > $this->lastrun) {
        $changed[] = $file->path;
        $file->changed = true;
      }
    }
    return $changed;
  }

It's this Line: $path = explode(":", $file->path)[0];
Explode the Path -> it's just C (should be "'C:/apache2/htdocs/site/migrate.php'")

When i remove the explode the "C" Error is gone, but the repeater error remains.

  • Thanks 1
Link to comment
Share on other sites

In RepeaterPage on line 114 it tries to access the property "name" of some object. So you could do this one line above:

if(!is_object($yourObjectVariable)) bd(Debug::backtrace());

// or this
if(!is_object($yourObjectVariable)) throw new WireException("should be an object");

// or this
if(!$yourObjectVariable instanceof Wire)) throw new WireException("should be instance of wire");

The backtrace should then maybe have some insights for us...

Link to comment
Share on other sites

15 hours ago, bernhard said:

The backtrace should then maybe have some insights for us...

Okay here we go ? 

Quote

German:
Fehler beim initieren von Modul: MagicPages - should be an object

English:
Error while initiating module: MagicPages - should be an object

"$grandparent" is NULL... checked it with a bd()

And here's the Screenshot:

478669435_2022-09-2109_30_17-Modul_RockMigrations.thumb.png.7892f2d5b71a04838aa1ede74ed2073d.png

  • Like 2
Link to comment
Share on other sites

Thx to @gebeer we now have support for repeater fields in the new version of RockMigrations ? If you find any other features that have been implemented in RM1 that are not yet in RM2 please let me know or even better create a PR ? 

Bumped version to 2.0.0 as I just realised that this version number fits better to how I'm referencing RM1 and RM2!

  • Like 1
  • Thanks 2
Link to comment
Share on other sites

  • bernhard changed the title to RockMigrations 🦸🚢 The Ultimate Automation and Deployment-Tool for ProcessWire
On 9/19/2022 at 12:23 PM, zoeck said:

Woah... i love the MagicPages Feature ?

MagicPages (eg HomePage.php) do now also load the related CSS and JS files (eg HomePage.js and HomePage.css) in the backend page editor ?

And there is a new WIKI page about MagicPages: https://github.com/baumrock/RockMigrations/wiki/MagicPages

Magic Assets

If your page is a MagicPage it will load YourPage.css and YourPage.js files automatically in the PW backend when editing any page of type YourPage.

Example:

// /site/classes/HomePage.php

// /site/classes/HomePage.css
div { outline: 2px solid red; }

// /site/classes/HomePage.js
alert('You are editing the HomePage');
  • Like 3
Link to comment
Share on other sites

  • 2 weeks later...

Hi @bernhard

I was using version 1 of RockMigrations until now and I am evaluating how to use this new version.

I encounter a bug with the use of fieldsets in a FieldtypeRepeater. The fieldsets does not contain any of the defined fields. the order must then be applied for it to be taken into account.

For example :

$rm->createField('rep_test', 'FieldtypeRepeater', [
    'repeaterFields' => ['gp_main', 'title', 'gp_main_END']
]);

Result :

  1. gp_main
  2. gp_main_END
  3. title

And then if I do :

$rep = $rm->getField('rep_test', true);
$rm->setFieldOrder(['gp_main', 'title', 'gp_main_END'], $rep->type->getRepeaterTemplate($rep));

The new order is apply and it's OK:

  1. gp_main
    1. title
  2. gp_main_END

Is it possible to apply the correct order with the use of the createField method?

Link to comment
Share on other sites

@bernhard Great video! The thing that I was confused about with RockMigrations (and the video doesn't address directly but I think I'm finally understanding anyway) is that it is about declarative template/field configurations that can be modified at any time rather than a series of instructions for updating PW. (When I think of the word "migrations", it makes me think more of files or snippets of code that apply a certain sequential set of changes for a specific feature.)

So I my question now is, can I just have a single migrate.php file that has ALL of the fields and templates defined in it? Or maybe a separate file for fields and one for templates? What's the advantage of tying the migration with the page class like you did in the video vs. doing it that way?  (I can see how if you built a feature you wanted to use on multiple sites (like a shopping cart) that having a separate migrate function would be better for that).

My other question is what is triggering the migration to run in your video? Does the default migrate.php file just run on every page load, or just in the page editor? I would probably only want it to run via CLI.

Thanks!

Link to comment
Share on other sites

11 hours ago, thetuningspoon said:

@bernhard Great video! The thing that I was confused about with RockMigrations (and the video doesn't address directly but I think I'm finally understanding anyway) is that it is about declarative template/field configurations that can be modified at any time rather than a series of instructions for updating PW. (When I think of the word "migrations", it makes me think more of files or snippets of code that apply a certain sequential set of changes for a specific feature.)

Thx 🙂 Yeah that's the usual way of doing migrations. I started like this at the very beginning, always creating a file with an upgrade() and a downgrade() method. But the declarative syntax is just so much better! It's easier and a lot faster to write (develop) and it's easier to read (understand) and it's also a lot easier when looking at git diffs:

yE9hcqw.png

You instantly see what I did here: Renamed the field constant from field_persons to field_personimages and added the field_personmatrix below the field_footermenu. And you can simply go back and forth in time by using your IDE:

VzJ668t.png

11 hours ago, thetuningspoon said:

So I my question now is, can I just have a single migrate.php file that has ALL of the fields and templates defined in it? Or maybe a separate file for fields and one for templates? What's the advantage of tying the migration with the page class like you did in the video vs. doing it that way?  (I can see how if you built a feature you wanted to use on multiple sites (like a shopping cart) that having a separate migrate function would be better for that).

You could do that. The easiest way is to put everything into migrate.php; It's the same as with hooks. Where do you place your hooks? All in ready.php? Maybe you started like this. But likely you'll not do so any more and have most of them in dedicated modules where you bundle things that belong together. As you said that has the huge benefit of making things reusable. Since I've adopted that approach I'm developing faster than ever before. But to get started just go ahead with migrate.php 😉 

Regarding your question about one file for fields and one for templates. You can do so. It's maybe a matter of preference. But I prefer to put everything in modules or pageclasses. Let's say we create a blog. We need a "blogitem" pageclass and that pageclass uses fields "title", "date", "content":

<?php namespace ProcessWire;

use RockMigrations\MagicPage;

class BlogItemPage extends Page {
  use MagicPage;
  public function migrate()
  {
    $rm = $this->rockmigrations();
    $rm->migrate([
      // field migrations
      'fields' => [
        'date' => [...],
        'content' => [...],
      ],
      // template migrations
      'templates' => [
        'blog-item' => [
          'icon' => '...',
          'fields' => [
            'title' => ['columnWidth' => 70],
            'date' => ['columnWidth' => 30],
            'content',
          ],
        ],
      ],
    ]);
  }
}

Do you understand what it is doing? At first sight? Or would it have been easier if the migrations lived in fields.php and templates.php ?

Also a thing to keep in mind is that sometimes the order of execution matters. And that's easier to handle if you place your migrations in places that belong logically together. That situation often arises when I'm writing migrations for parent/child template relations. The concept is as follows:

  • Have a master module (I recommend having a Site.module.php for every project and the default migrations profile does that for you 🙂 )
  • Load pageclasses from the master module (eg BlogItems and BlogItem)
  • Trigger migrations in every pageclass (RM has helpers for that, see https://github.com/baumrock/RockMigrations/wiki/Ship-your-Module-with-Custom-Page-Classes )
    • That takes care of creating all fields for the template and adding fields to the template (like the example above)
  • THEN set parent/child relationship (both templates need to exist before we can set this relation!)
    • This makes the backend now that if you create a new page under "BlogItems" you are only allowed to add a single "BlogItem"

Does that make sense so far?

11 hours ago, thetuningspoon said:

My other question is what is triggering the migration to run in your video? Does the default migrate.php file just run on every page load, or just in the page editor? I would probably only want it to run via CLI.

RockMigrations runs on every single request. Then it checks all the files that have been added to the watchlist (migrate.php is added by default, others can be added via $rm->watch(...)) and it will run the migrations for every file in the watchlist that has been changed since the last run of migrations. So if you had 30 files watched and you change one (let's say "BlogItem.php"), then only migrations of this file will be migrated. All others will be skipped. You can inspect that easily via the tracy logs panel where you see what is going on and in which order:

rGegvFL.png

Now if you combine that with RockFrontend, then you get instant reloads of the backend and therefore instant migrations while you code. So great, you have to try it!

If you run migrations from the cli or you do a modules::refresh then all migrations are run (just in case the watcher does not catch up a file or something goes wrong):

Js6PYKB.png

If you still have any questions let me know 🙂 Also I'm happy to do consulting via online meeting if you have questions specific to a project (or want to support me and the development of my modules).

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • 2 weeks later...

Hey @bernhard,

I'm considering RockMigrations for a new project, but would very much prefer to install it via Composer to avoid bundling module code with project code, make updates easier, etc. I noticed that your old RockMigrations project had a composer.json in place, so would you mind adding that here as well, and preferably also submitting the package to packagist.org?

 Thanks in advance! 🙂

Note that I would recommend using the options outlined here: 

... instead of hari/pw-module. The installer plugin from Hari was updated a while ago to support Composer 2, but it still lacks support for custom modules directory, for an example. In my opinion it would be best to eventually migrate modules to use composer/installers, since that's the "official" solution.

  • Like 1
Link to comment
Share on other sites

  • bernhard changed the title to RockMigrations 🚀🚀 The Ultimate Automation and Deployment-Tool for ProcessWire

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...