We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 14549
    • 8 Posts


    Newest version 0.21 pasted below
    // &database=Database Name;string;example &live_prefix=Table prefix for live site;string;modx_ &staging_prefix=Table prefix for staging site;string;modxstaging_ &live_path=Path to live site, relative to shared parent;string;/var/www/sites/default/htdocs/example/ &staging_path=Path to staging site, relative to shared parent;string;/var/www/sites/default/htdocs/example_staging/ &rm_path=Location of rm binary;string;/bin/rm &rsync_path=Location of rsync binary;string;/usr/bin/rsync 
    //
    // modx_staging
    // Author: John Susek
    // Email: [email protected]
    
    $modx_staging_version  = "0.21";
     
    $tables_to_deploy = array(
        "$staging_prefix"."active_users"                => 1,
        "$staging_prefix"."categories"                  => 1,
        "$staging_prefix"."documentgroup_names"         => 1,
        "$staging_prefix"."document_groups"             => 1,
        "$staging_prefix"."keyword_xref"                => 1,
        "$staging_prefix"."membergroup_access"          => 1,
        "$staging_prefix"."membergroup_names"           => 1,
        "$staging_prefix"."member_groups"               => 1,
        "$staging_prefix"."site_content"                => 1,
        "$staging_prefix"."site_content_metatags"       => 1,
        "$staging_prefix"."site_htmlsnippets"           => 1,
        "$staging_prefix"."site_keywords"               => 1,
        "$staging_prefix"."site_metatags"               => 1,
        "$staging_prefix"."site_modules"                => 1,
        "$staging_prefix"."site_module_access"          => 1,
        "$staging_prefix"."site_module_depobj"          => 1,
        "$staging_prefix"."site_plugins"                => 1,
        "$staging_prefix"."site_plugin_events"          => 1,
        "$staging_prefix"."site_snippets"               => 1,
        "$staging_prefix"."site_templates"              => 1,
        "$staging_prefix"."site_tmplvars"               => 1,
        "$staging_prefix"."site_tmplvar_access"         => 1,
        "$staging_prefix"."site_tmplvar_contentvalues"  => 1,
        "$staging_prefix"."site_tmplvar_templates"      => 1,
        "$staging_prefix"."system_eventnames"           => 1,
        "$staging_prefix"."system_settings"             => 1,
        "$staging_prefix"."webgroup_access"             => 1,
        "$staging_prefix"."webgroup_names"              => 1,
        "$staging_prefix"."web_groups"                  => 1,
        "$staging_prefix"."web_users"                   => 1,
        "$staging_prefix"."web_user_attributes"         => 1,
        "$staging_prefix"."web_user_settings"           => 1,
        "$staging_prefix"."manager_log"                 => 1,
        "$staging_prefix"."manager_users"               => 1
    );
    
    $tables_to_reverse_deploy = array(
        "$live_prefix"."event_log"           => 1,
        "$live_prefix"."jot_content"         => 1,
        "$live_prefix"."jot_subscriptions"   => 1,
        "$live_prefix"."user_attributes"     => 1,
        "$live_prefix"."user_messages"       => 1,
        "$live_prefix"."user_roles"          => 1,
        "$live_prefix"."user_settings"       => 1
    );
    
    
        
        
        
    print "<style>table { border-collapse:collapse;border:1px solid gray;margin:13px;} td { border:1px solid gray;padding:4px; } h2, h3, h4 { color:#264F17; margin:5px 15px;font-family: sans-serif; } .shell { margin:15px;padding:5px;background:black; color:white; border:2px solid gray; } p { margin:15px; } .gray { color:gray;margin:0 15px; } .success { padding:5px;background-color:rgb(143,199,12);color:#264F17; } .success2 { padding:5px;color:#264F17; }</style>";  
    
    if (!$_POST["deploy"])
    {
        // Display the UI
        print "<FORM action='".$_SERVER['REQUEST_URI']."' method='post'>
                    <h2>MODx Deploy</h2>
                    <br/><h3>Would you like to deploy to the live site?</h3>";
        
        print "<p class='success'>
                <INPUT type='hidden' name='deploy' value='deploy'>
                <INPUT type='submit' value='Deploy'>
                </p></FORM>";
    
    
        print "<br/><h3>Configuration overview</h3><pre><table border='0' style='border:0'>
                <tr><td>Database</td><td></td><td>$database</td></tr>
                <tr><td>Table prefix</td><td>Staging</td><td>$staging_prefix</td></tr>
                <tr><td></td><td>Live</td><td>$live_prefix</td></tr>
                <tr><td>Deploy</td><td>From Staging</td><td>$staging_path</td></tr>
                <tr><td></td><td>To Live</td><td>$live_path</td></tr></p>              
                <tr><td>Tables to deploy</td><td></td><td><pre>";                
        print_r($tables_to_deploy);
        print "</pre></td></tr><tr><td>Tables to reverse deploy</td><td></td><td><pre>";
        print_r($tables_to_reverse_deploy);
        print "</pre></td></tr></table></pre>";
    
    }
    else
    {
    	// Do the table copying
        print "<h2>MODx Deploy</h2><pre>";
    
        $rsync_cmd = "$rsync -a --exclude=assets/cache --exclude=config.inc.php $staging_path $live_path;";
        print "<h3 title='$rsync_cmd'>Syncing filesystems...</h3><div class='shell'>";   
        print shell_exec("$rsync_cmd");
        print "<b>done.</b></div>";
    
        print "<h3>Clearing caches...</h3><div class='shell'>";   
        print shell_exec("$rm -f $live_path/assets/cache/*pageCache.php");
        print shell_exec("$rm -f $staging_path/assets/cache/*pageCache.php");    
        print "<b>done.</b></div>";
    
    
        $sql = "SHOW TABLES FROM $database";
        print "<h3 title='$sql'>Getting list of tables from database '$database'...</h3><div class='shell'>";   
        $results = $modx->db->query($sql);
        print "<b>done.</b></div>";
    
        print "<h3>Syncing tables...</h3>";   
        print "<table>";
        while( $row = $modx->db->getRow($results) ) {
            
            $table = $row["Tables_in_$database"];
            
            if ( preg_match("/$staging_prefix/", $table) ) // if this table is a staging table..
            {
            
                if ($tables_to_deploy["$table"])
                {
                	$counterpart = str_replace("$staging_prefix", "$live_prefix", $table);
                	print "<tr><td>$table</td><td>---></td><td>$counterpart</td>";
        
                	$sql_drop = "DROP TABLE IF EXISTS `$counterpart`"; 
                	if (!$modx->db->query($sql_drop))
                    {
                	   print "Error dropping live table! SQL statement used: <br/>$sql_drop<br/>";
                    }
        
                	$sql_create = "CREATE TABLE `$counterpart` LIKE `$table`";
                	if (!$modx->db->query($sql_create))
                	{
                	   print "Error creating new live table from staging table! SQL statement used: <br/>$sql_create<br/>";
                    }
    
        
                	$sql_populate = "INSERT INTO `$counterpart` SELECT * FROM `$table`";
                	if ($modx->db->query($sql_populate))
                	{
                       print "<td class='success2' title='$sql_drop ; $sql_create ; $sql_populate'>✔</td></tr>";
                    }
                    else
                    {
                	   print "Error populating new live table from staging table. SQL statement used: <br/>$sql_populate<br/>";
                    }
                    
                }
                
            }
            elseif ( preg_match("/$live_prefix/", $table) ) // if a live table..
            {
            
                if ($tables_to_reverse_deploy["$table"])
                {
                	$counterpart = str_replace("$live_prefix", "$staging_prefix", $table);
                	print "<tr><td>$counterpart</td><td><---</td><td>$table</td>";
                	
                	$sql_drop = "DROP TABLE IF EXISTS `$counterpart`"; 
                	if (!$modx->db->query($sql_drop))
                    {
                	   print "Error dropping staging table: <br/>$sql_drop<br/>";
                    }
                    
                	
                	$sql_create = "CREATE TABLE `$counterpart` LIKE `$table`";
                	if (!$modx->db->query($sql_create))
                	{
                	   print "Error creating new staging table from live table! SQL statement used: <br/>$sql_create<br/>";
                    }
    
    
                	$sql_populate = "INSERT INTO `$counterpart` SELECT * FROM `$table`";
                	if ($modx->db->query($sql_populate))
                	{
                       print "<td class='success2' title='$sql_drop ; $sql_create ; $sql_populate'>✔</td></tr>";
                    }
                    else
                    {
                	   print "Error creating new staging table from live table. SQL statement used:<br/>$sql_populate<br/>";
                    }
                   
                }
            } 
            else // else another table without either prefix, dont touch
            {  
                 
               	print "<br/>Other table (ignoring): $table<br/>";
               	
            }   
            
        }
        print "</table>";
        print "<h3 class='success2'>✔ Site deployed successfully.</h3>";    
        print "</p></pre>";
    
    }
    
    
    


    For module configuration, use this string:
    
    &database=Database Name;string;example &live_prefix=Table prefix for live site;string;modx_ &staging_prefix=Table prefix for staging site;string;modxstaging_ &live_path=Path to live site, relative to shared parent;string;/var/www/sites/default/htdocs/example/ &staging_path=Path to staging site, relative to shared parent;string;/var/www/sites/default/htdocs/example_staging/ &rm_path=Location of rm binary;string;/bin/rm &rsync_path=Location of rsync binary;string;/usr/bin/rsync 
    
    
    
    Changelog
    -----
    0.21 FIXED: Indexes and restraints were not getting duplicated with the tables.
    0.2  Use configuration variables
    0.1  Initial release


      • 7231
      • 4,205 Posts
      Welcome to the forum.

      The ’draft mode’ otherwise known as a ’staging area’ is a common request. The most common solution is to have 2 servers a staging server where all the editing takes place and a production server which is what the web sees. Then once editing is done you do a database dump and svn any file changes. This is not an easy solution but seems to be the most solid approach.

      There is also the ContentHistory plug-in that allows you to have versioning and makes it easy to go back to previous versions of content. However to preview the editor will first need to commit.
        [font=Verdana]Shane Sponagle | [wiki] Snippet Call Anatomy | MODx Developer Blog | [nettuts] Working With a Content Management Framework: MODx

        Something is happening here, but you don&#39;t know what it is.
        Do you, Mr. Jones? - [bob dylan]
        • 20413
        • 2,877 Posts
        One approach is to create documents but not set them public published. Then have the boss log into another folder where duplicates of these docs are set public published.
        There is this --> http://modxcms.com/forums/index.php/topic,30589.0.html
        But rather have them login on a webpage.
          @hawproductions | http://mrhaw.com/

          Infograph: MODX Advanced Install in 7 steps:
          http://forums.modx.com/thread/96954/infograph-modx-advanced-install-in-7-steps

          Recap: Portland, OR (PDX) MODX CMS Meetup, Oct 6, 2015. US Bancorp Tower
          http://mrhaw.com/modx_portland_oregon_pdx_modx_cms_meetup_oct_2015_us_bancorp_tower
          • 14549
          • 8 Posts
          Thanks guys! The staging server idea sounds pretty good, but will be a bit of a pain. I’m figuring out right now if it’s worth the time to write a plugin for this. If something usable comes out of it, I’ll try to share with everyone. Thanks
            • 6726
            • 7,075 Posts
            Defining a status for a document, triggering an email to a reviewer to approve the document, falls (I think) into the current discussion about Workflow in modx.

            Feel free to jump in an contribute ideas smiley

              .: COO - Commerce Guys - Community Driven Innovation :.


              MODx est l&#39;outil id
              • 14549
              • 8 Posts
              Okay, I’ve created a module to get a little practice with modx and php. grin

              This will synchronize two modx installations, both at the filesystem level and the database table level. You can choose which tables get copied to the live site. I’ve written up some notes along with the module; could someone try this and let me know if they find it useful? I can clean it up a bit, or add features, if there is interest.

              I’m calling it modx_staging for reference. Please read the notes and try to get it working with two newly linked installs! Copy and paste contents of staging.txt to a new module (I’ve also included source code in this post). Name the module "Deploy to Live Site" or something like that.

              I think this should be useful to some... give it a try!

              EDIT:

              Here are some simpler instructions, so you don’t have to read through the rambling notes file.

              1. Install two modx 0.9.6.3 installations to the same web server. These two installs are referred to as the live-site and the staging-site.
              
              2. Point them both to the same SQL server.  Use identical settings for both of them, but give each installation a unique table prefix (I like modx_ for live and modxstaging_ for staging). 
              
              3. Log into staging-site manager. Copy and paste modx_staging 0.1 source code into a new module. Modify variables at the top of the source code to match your installation. Name the module 'Deploy to Live Site'. 
              
              4. Now, when you use the module, you will see a Deploy button. Click it and it will copy content from the staging-site to the live-site. 
              
              5. To tweak what tables get moved between the staging-site and live-site, modify the $tables_to_deploy variable in the source.



              
              // modx_staging
              // Author: John Susek
              // Email: [email protected]
              // License: CC Attribution 2.5
              
              $modx_staging_version  = "0.1";
              
              $modx_staging_database = 'example';
              $staging_prefix        = 'modxstaging_';
              $prefix                = 'modx_';
              
              $sites_path       = '/var/www/sites/default/htdocs/';
              $live_path        = 'example/';
              $staging_path     = 'example_staging/';
              $rsync            = "/usr/bin/rsync";
              $rm               = "/bin/rm";
               
              $tables_to_deploy = array(
                  "$staging_prefix"."active_users"                => 1,
                  "$staging_prefix"."categories"                  => 1,
                  "$staging_prefix"."documentgroup_names"         => 1,
                  "$staging_prefix"."document_groups"             => 1,
                  "$staging_prefix"."keyword_xref"                => 1,
                  "$staging_prefix"."membergroup_access"          => 1,
                  "$staging_prefix"."membergroup_names"           => 1,
                  "$staging_prefix"."member_groups"               => 1,
                  "$staging_prefix"."site_content"                => 1,
                  "$staging_prefix"."site_content_metatags"       => 1,
                  "$staging_prefix"."site_htmlsnippets"           => 1,
                  "$staging_prefix"."site_keywords"               => 1,
                  "$staging_prefix"."site_metatags"               => 1,
                  "$staging_prefix"."site_modules"                => 1,
                  "$staging_prefix"."site_module_access"          => 1,
                  "$staging_prefix"."site_module_depobj"          => 1,
                  "$staging_prefix"."site_plugins"                => 1,
                  "$staging_prefix"."site_plugin_events"          => 1,
                  "$staging_prefix"."site_snippets"               => 1,
                  "$staging_prefix"."site_templates"              => 1,
                  "$staging_prefix"."site_tmplvars"               => 1,
                  "$staging_prefix"."site_tmplvar_access"         => 1,
                  "$staging_prefix"."site_tmplvar_contentvalues"  => 1,
                  "$staging_prefix"."site_tmplvar_templates"      => 1,
                  "$staging_prefix"."system_eventnames"           => 1,
                  "$staging_prefix"."system_settings"             => 1,
                  "$staging_prefix"."webgroup_access"             => 1,
                  "$staging_prefix"."webgroup_names"              => 1,
                  "$staging_prefix"."web_groups"                  => 1,
                  "$staging_prefix"."web_users"                   => 1,
                  "$staging_prefix"."web_user_attributes"         => 1,
                  "$staging_prefix"."web_user_settings"           => 1,
                  "$staging_prefix"."manager_log"                 => 1,
                  "$staging_prefix"."manager_users"               => 1
              );
              
              $tables_to_reverse_deploy = array(
                  "$prefix"."event_log"           => 1,
                  "$prefix"."jot_content"         => 1,
                  "$prefix"."jot_subscriptions"   => 1,
                  "$prefix"."user_attributes"     => 1,
                  "$prefix"."user_messages"       => 1,
                  "$prefix"."user_roles"          => 1,
                  "$prefix"."user_settings"       => 1
              );
              
              
                  
                  
                  
              print "<style>table { border-collapse:collapse;border:1px solid gray;margin:13px;} td { border:1px solid gray;padding:4px; } h2, h3, h4 { color:#264F17; margin:5px 15px;font-family: sans-serif; } .shell { margin:15px;padding:5px;background:black; color:white; border:2px solid gray; } p { margin:15px; } .gray { color:gray;margin:0 15px; } .success { padding:5px;background-color:rgb(143,199,12);color:#264F17; } .success2 { padding:5px;color:#264F17; }</style>";  
              
              if (!$_POST["deploy"])
              {
              
                  print "<FORM action='".$_SERVER['REQUEST_URI']."' method='post'>
                              <h2>MODx Deploy</h2>
                              <br/><h3>Would you like to deploy to the live site?</h3>";
                  
                  print "<p class='success'>
                          <INPUT type='hidden' name='deploy' value='deploy'>
                          <INPUT type='submit' value='Deploy'>
                          </p></FORM>";
              
              
                  print "<br/><h3>Configuration overview</h3><pre><table border='0' style='border:0'>
                          <tr><td>Database</td><td></td><td>$modx_staging_database</td></tr>
                          <tr><td>Table prefix</td><td>Staging</td><td>$staging_prefix</td></tr>
                          <tr><td></td><td>Live</td><td>$prefix</td></tr>
                          <tr><td>Deploy</td><td>From Staging</td><td>$sites_path$staging_path</td></tr>
                          <tr><td></td><td>To Live</td><td>$sites_path$live_path</td></tr></p>              
                          <tr><td>Tables to deploy</td><td></td><td><pre>";                
                  print_r($tables_to_deploy);
                  print "</pre></td></tr><tr><td>Tables to reverse deploy</td><td></td><td><pre>";
                  print_r($tables_to_reverse_deploy);
                  print "</pre></td></tr></table></pre>";
              
              }
              else
              {
                          
                  print "<h2>MODx Deploy</h2><pre>";
              
                  $rsync_cmd = "cd $sites_path; $rsync -a --exclude=assets/cache --exclude=config.inc.php $staging_path $live_path;";
                  print "<h3 title='$rsync_cmd'>Syncing filesystems...</h3><div class='shell'>";   
                  print shell_exec("$rsync_cmd");
                  print "<b>done.</b></div>";
              
                  print "<h3>Clearing caches...</h3><div class='shell'>";   
                  print shell_exec("$rm $sites_path/$live_path/assets/cache/*pageCache.php");
                  print shell_exec("$rm $sites_path/$staging_path/assets/cache/*pageCache.php");    
                  print "<b>done.</b></div>";
              
              
                  $sql = "SHOW TABLES FROM $modx_staging_database";
                  print "<h3 title='$sql'>Getting list of tables from database '$modx_staging_database'...</h3><div class='shell'>";   
                  $results = $modx->db->query($sql);
                  print "<b>done.</b></div>";
              
                  print "<h3>Syncing tables...</h3>";   
                  print "<table>";
                  while( $row = $modx->db->getRow($results) ) {
                      
                      $table = $row["Tables_in_$modx_staging_database"];
                      
                      if ( preg_match("/$staging_prefix/", $table) )// if this table is a staging table..
                      {
                      
                          if ($tables_to_deploy["$table"])
                          {
                          	$counterpart = str_replace("$staging_prefix", "$prefix", $table);
                          	print "<tr><td>$table</td><td>---></td><td>$counterpart</td>";
                  
                          	$sqld = "DROP TABLE IF EXISTS `$counterpart`"; 
                          	if (!$modx->db->query($sqld))
                              {
                          	   print "Error dropping live table:<br/>$sqld<br/>";
                              }
                  
                  
                          	$sql = "CREATE TABLE IF NOT EXISTS `$counterpart` SELECT * FROM `$table`";
                          	if ($modx->db->query($sql))
                          	{
                                 print "<td class='success2' title='$sqld ; $sql'>✔</td></tr>";
                              }
                              else
                              {
                          	   print "Error creating new live table from staging table. SQL statement used:<br/>$sql<br/>";
                              }
                              
                          }
                          
                      }
                      elseif ( preg_match("/$prefix/", $table) ) // if a live table..
                      {
                      
                          if ($tables_to_reverse_deploy["$table"])
                          {
                          	$counterpart = str_replace("$prefix", "$staging_prefix", $table);
                          	print "<tr><td>$counterpart</td><td><---</td><td>$table</td>";
                          	
                          	$sqld = "DROP TABLE IF EXISTS `$counterpart`"; 
                          	if (!$modx->db->query($sqld))
                              {
                          	   print "Error dropping staging table:<br/>$sqld<br/>";
                              }
                              
                          	
                          	$sql = "CREATE TABLE IF NOT EXISTS `$counterpart` SELECT * FROM `$table`";
                          	if ($modx->db->query($sql))
                          	{
                                 print "<td class='success2' title='$sqld ; $sql'>✔</td></tr>";
                              }
                              else
                              {
                          	   print "Error creating new staging table from live table. SQL statement used:<br/>$sql<br/>";
                              }
                             
                          }
                      } 
                      else // else another table without either prefix, dont touch
                      {  
                           
                         	print "<br/>Other table (ignoring): $table<br/>";
                         	
                      }   
                      
                  }
                  print "</table>";
                  print "<h3 class='success2'>✔ Site deployed successfully.</h3>";    
                  print "</p></pre>";
              
              }
              
              
                • 16183
                • 1,390 Posts
                Quote from: johnsolo at Jan 25, 2009, 07:04 AM

                Okay, I’ve created a module to get a little practice with modx and php. grin

                This will synchronize two modx installations, both at the filesystem level and the database table level. You can choose which tables get copied to the live site. I’ve written up some notes along with the module; could someone try this and let me know if they find it useful? I can clean it up a bit, or add features, if there is interest.

                I’m calling it modx_staging for reference. Please read the notes and try to get it working with two newly linked installs! Copy and paste contents of staging.txt to a new module (I’ve also included source code in this post). Name the module "Deploy to Live Site" or something like that.


                Hmmm, this looks interesting. Unfortunately ATM I don’t have time to give it a whirl....will follow its progress closely though...Thx John

                /k
                  • 7231
                  • 4,205 Posts
                  I like this, thanks grin I will need to check this out with some attention, however, in looking at the code I already have one question. There are a few snippets that create custom tables (maxigallery and jot for example). How would we add more tables to be included in the transfer?

                    [font=Verdana]Shane Sponagle | [wiki] Snippet Call Anatomy | MODx Developer Blog | [nettuts] Working With a Content Management Framework: MODx

                    Something is happening here, but you don&#39;t know what it is.
                    Do you, Mr. Jones? - [bob dylan]
                    • 14549
                    • 8 Posts
                    Quote from: dev_cw at Jan 25, 2009, 11:41 AM

                    I like this, thanks grin I will need to check this out with some attention, however, in looking at the code I already have one question. There are a few snippets that create custom tables (maxigallery and jot for example). How would we add more tables to be included in the transfer?

                    To add more tables to be included in transfer from staging-site to live-site, add a line like this to $tables_to_deploy array:

                        "$staging_prefix"."your_table_name"                => 1,
                    


                    To add more tables to be included in transfer from live-site to staging-site, add a line like this to $tables_to_reverse_deploy array:

                        "$prefix"."your_table_name"                => 1,
                    

                      • 14549
                      • 8 Posts
                      Also, I was thinking, if this module becomes more popular, I could add a way for snippet authors to indicate which way they want to sync their tables. Right now, by default, unknown tables are simply ignored and not touched. See modx_staging.rtf for notes.