We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 813 ☆ A M B ☆
    • 326 Posts
    I’m working on a plugin for Evo that will serve as a VERY simple rollback mechanism when writing snippets, using the OnBeforeSnipFormSave system event. I’ve got the basic concept working, but I don’t know how to grab all of the snippet’s code via the plugin. I’ve tried using $modx->documentOutput; but it doesn’t seem to return anything.

    Any suggestions? Thanks!
      • 3749
      • 24,544 Posts
      See if it’s in $_POST[’snippet’].
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 813 ☆ A M B ☆
        • 326 Posts
        Hmmm...that may do the trick, but suddenly it’s stopped working altogether. Here’s what I have so far. It has occurred to me that I have a very weak understanding of how plugins should be coded smiley

        $out = &$modx->documentOutput;
        
        $table = 'modx_rollback';    
        $fields = array(
            'content' => $out
        );
        
        $modx->db->update($fields, $table);


        The only system event checked is "OnBeforeSnipFormSave". I’m on Evo 1.0.3.

        At this point, all I want to do is this: when I’m editing a snippet and hit "save," all of the content in my snippet gets entered into a simple one-column table in the database. I’m not sure what I’ll do with the data at that point, but it seems like a good starting point for a simple "undo" system.

        Does my approach make sense? What is it about my code that isn’t clicking? Thanks for the help!
          • 3749
          • 24,544 Posts
          It’s been so long since I worked with Evo I’m not sure.

          BTW, you might be able to hook it to OnSnipFormSave instead, which fires after the data is written to the DB.

          In both events, the only variables available directly are $id (the snippet’s ID) and $mode (’new’ or ’upd’).

          Using OnSnipFormSave, you could get the data from the DB by getting the the ’snippet’ field from that snippet’s record in the modx_site_snippets table.
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 813 ☆ A M B ☆
            • 326 Posts
            Getting closer! Using OnSnipFormSave and $id as you suggested, here’s what I’ve got so far:

            if (!empty($id)) {
                $sql = $modx->db->query('SELECT snippet FROM `vid_site_snippets` WHERE id='.$id.'');
                $resultArray = $modx->db->makeArray( $sql );
                foreach($resultArray as $item) {
                    $snippetCode = $item['snippet'];
                }
            }
            
            $table = 'modx_rollback';    
            $fields = array(
                'content' => ''.$snippetCode.''
            );
            
            $modx->db->delete(''.$table.'');
            $modx->db->insert( $fields, $table);


            However, that spits out an error because $snippetCode contains raw PHP, and I think it’s mixing it into my INSERT statement and blowing up (if I pull a different field that’s just an integer or simple string, it works). What’s the proper way to escape or encode the PHP I’m getting back so that it’s interpreted as a string and not as raw PHP? I’m assuming I could use the same method used in the MODx manager to save the snippet in the first place, but I’m having trouble finding that method in the manager files.

            Thanks!
              • 813 ☆ A M B ☆
              • 326 Posts
              Oh wait! I think I got it. I just used addslashes on the foreach loop, like so:

              if (!empty($id)) {
                  $sql = $modx->db->query('SELECT snippet FROM `vid_site_snippets` WHERE id='.$id.'');
                  $resultArray = $modx->db->makeArray( $sql );
                  foreach($resultArray as $item) {
                      $snippetCode = addslashes($item['snippet']);
                  }
              }
              
              $table = 'vid_rollback';    
              $fields = array(
                  'content' => $snippetCode
              );
              
              $modx->db->delete(''.$table.'');
              $modx->db->insert( $fields, $table);
              


              That’s getting it into the DB exactly how I want. Thanks! Does that seem okay? I’m not sure how useful this will be or how to best implement it, but it seems like an improvement over having no "undo" option when writing snippets.
                • 3749
                • 24,544 Posts
                I think it’s a cool idea. smiley

                It will be a challenge to implement the UI, but I think a lot of people would love to have the ability to roll back elements (and resources too).
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 813 ☆ A M B ☆
                  • 326 Posts
                  Yeah...that whole interface thing smiley I usually have MODx on one screen and a DB gui called Sequel Pro (http://www.sequelpro.com/) on my second monitor, so this is usable in its current state for me. However, I’m thinking it could be really useful for the community to have it available as a plugin that works with the manager. I think my plan at this point is not to invest any additional time into manager integration for Evo, but to possibly pick it up again after I’m more familiar with Revo (starting my first bigger project in it next week!). Speaking of which, when is your Revo book coming out? I’m dying to have a good Revo reference book.

                  Oh, and one last posting of the code. I added a second table column called "content_previous." When you hit save in a snippet, it takes what’s in the "content" column and moves it to "content_previous," and then puts the latest save into "content." Not very elegant, but it works!

                  if (!empty($id)) {
                      $sqlNewValue = $modx->db->query('SELECT snippet FROM `vid_site_snippets` WHERE id='.$id.'');
                      $resultArrayNewValue = $modx->db->makeArray( $sqlNewValue );
                      foreach($resultArrayNewValue as $item) {
                          $snippetCodeNew = addslashes($item['snippet']);
                      }
                  
                      $sqlOldValue = $modx->db->query('SELECT content FROM `vid_rollback`');
                      $resultArrayOldValue = $modx->db->makeArray( $sqlOldValue );
                      foreach($resultArrayOldValue as $item) {
                          $snippetCodeOld = addslashes($item['content']);
                      }
                  
                      $table = 'vid_rollback';    
                      $fields = array(
                          'content' => $snippetCodeNew,
                          'content_previous' => $snippetCodeOld
                      );
                  
                  
                  
                      $modx->db->delete(''.$table.'');
                      $modx->db->query('ALTER TABLE '.$table.' AUTO_INCREMENT = 1');
                  
                      $modx->db->insert( $fields, $table);
                  }
                  
                  
                  
                    • 3749
                    • 24,544 Posts
                    Glad you got it working. Thanks for reporting back. smiley

                    The book is nearing completion (I’m working on it day and night), but it’s hard to say how long it will be before the actual treeware is available.

                    I think your idea of using Revolution is a good one. In Revolution, your whole plugin would look something like this (once you had the schema set up for your custom table):

                    $newSnippet = $modx->newObject('modRollback');
                    $newSnippet = $snippet;
                    $newSnippet->save();


                    It’s also easier to modify Manager forms in Revo so you could just add a RollBack button to the Create/Edit Snippet form that would revert the snippet.

                      Did I help you? Buy me a beer
                      Get my Book: MODX:The Official Guide
                      MODX info for everyone: http://bobsguides.com/modx.html
                      My MODX Extras
                      Bob's Guides is now hosted at A2 MODX Hosting