<![CDATA[ Increment a TV on the "onDocFormSave" event. - My Forums]]> https://forums.modx.com/thread/?thread=99441 <![CDATA[Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event?page=2#dis-post-537761
I didn't know that this will be difficult to accomplish. But that's it. I have this small plugin that is fired on the "onDocFormSave" event to increment a TV value each time a resource is saved, in order to make a version system :
<?php
$resource->setTVValue('version', $resource->getTVValue('version') + 1);


If the resource page is not reloaded, the TV value is not incremented. I don't know why, but when we save the resource for the second time, it ALWAYS get the old tv value.

I tried to empty the cache between each save but it does not work.
I also tried to do this directly by using xPDO statements in the bdd :
$result = $modx->query("SELECT value FROM modx_site_tmplvar_contentvalues WHERE tmplvarid=2 AND contentid=$id");
$row = $result->fetch(PDO::FETCH_ASSOC);
$version = $row['value'] + 1;

$modx->query("UPDATE modx_site_tmplvar_contentvalues SET value=$version  WHERE tmplvarid=2 AND contentid=$id");


But the result is the same.

Does I have to use PDO statements to achieve this instead of using xPDO ?
Is there another way ? A cache to clean ? A variable reference to remove ?

Thanks for helping]]>
romainfallet Feb 03, 2016, 04:00 AM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event?page=2#dis-post-537761
<![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event?page=2#dis-post-538164 Quote from: sottwell at Feb 09, 2016, 04:50 PM
I'm not very reliable about getting anything put in, and I'm afraid if I make a way for people to submit suggestions it would cause hurt feelings if I simply didn't get around to using it.

Amen to that. I lie awake at night feeling guilty about all the people I've let down in that way.]]>
BobRay Feb 11, 2016, 02:34 PM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event?page=2#dis-post-538164
<![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event?page=2#dis-post-538093
I'm not very reliable about getting anything put in, and I'm afraid if I make a way for people to submit suggestions it would cause hurt feelings if I simply didn't get around to using it.]]>
sottwell Feb 09, 2016, 10:50 AM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event?page=2#dis-post-538093
<![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538080 modx doc.

Anyway, I didn't know the CookBook website, I am glad to be part of it. Is there a way to suggest some tricks ?]]>
romainfallet Feb 09, 2016, 03:14 AM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538080
<![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538060

Thanks for posting such a clear description of the steps. smiley]]>
BobRay Feb 08, 2016, 01:26 PM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538060
<![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538049 http://modxcookbook.com/basics/plugins/versioning-resources.html]]> sottwell Feb 08, 2016, 10:49 AM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538049 <![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538044
Here is my complete procedure to achieve my version system :

Step 1 :
Create a new table in the MODX database called "modx_site_content_version" with three columns "id", "contentid" and "version" (set "id" column as INDEX):
CREATE TABLE `modx_site_content_version` (
  `id` int(11) NOT NULL,
  `contentid` int(11) NOT NULL,
  `version` int(11) NOT NULL
) DEFAULT CHARSET=utf8;
ALTER TABLE `modx_site_content_version` ADD PRIMARY KEY(`id`);
ALTER TABLE `modx_site_content_version` CHANGE `id` `id` INT(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `modx_site_content_version` ADD INDEX(`id`);


Step 2 :
Create a new snippet called "createXpdoClasses" and fill it with this code (available at http://bobsguides.com/custom-db-tables.html, thanks to Bob):
<?php
/**
* @package = CreateXpdoClasses
*
* Create Xpdo Classes script
*
* This script creates xPDO-ready classes from existing custom
* database tables. Run it again whenever you change
* your schema.
*
* It assumes that your custom tables have been imported into
* the MODX DB and use a different table prefix than the MODX
* tables.
 
* In theory, you can use a separate DB but this has not been
* tested and the process of using the classes would be more
* complicated. To do this, you would need to set the
* following variables after including the config file,
* but before creating the $modx object:
* 
* $database_server = 'yourDbServer';
* $database_type = 'mysql';
* $dbase = 'yourDbName';
* $database_user = 'user';
* $database_password = 'password';
* $table_prefix = 'yourPrefix_';
*
* In the snippets that use the classes, you'd need to
* instantiate a new $xpdo object, and use $xpdo-> rather
* than $modx-> to call the methods.
* $xpdo = new xPDO('mysql:host=localhost;dbname=yourDbName',
*   $database_user,$database_password,$table_prefix);
*
* Note: If you are running this outside of MODX and testing
* it in the Manager, it will log you out when it runs, even
* though the Manager screen will still be visible. Actions
* taken in the Manager (e.g., saving a snippet) will not be
* successful. After running the script, reload the Manager
* page in your browser and you will be prompted to
* log back in.
*
*
*/
/* assume we're in a snippet */
$outsideModx = false;
 
 if (!defined('MODX_CORE_PATH')) {
     $outsideModx = true;
    /* put the path to your core in the next line to run
     * outside of MODX */
    define(MODX_CORE_PATH, 'c:/xampp/htdocs/test/core/');
    include_once MODX_CORE_PATH .
        '/model/modx/modx.class.php';
    $modx= new modX();
    $modx->initialize('mgr');
}
 
/* set these if running outside of MODX */
 
if ($outsideModx) {
    $myPackage = 'mypackage';
 
    /* table prefix; must match the prefix of the tables
     * to process. Using the same prefix as  the MODX
     * tables is not recommended */
    $myPrefix = 'bobs_';
 
    // $myTables = 'bobs_quotation';
}
 
 
/* These two switches let you write the schema and/or
 * create the classes; useful for debugging and for leaving
 * a manually edited schema file alone*/
 
$createSchema = $modx->getOption('createSchema',
    $scriptProperties,true);
$createClasses = $modx->getOption('createClasses',
    $scriptProperties,true);
 
/* Used to include the phpDoc templates below or
 * other custom templates */
$includeCustomTemplates = empty($includeCustomTemplates)?
false : $includeCustomTemplates;
 
/* $myPackage is the name of your package. Use this in
 * your addPackage() call to load all classes created
 * by this script.
 * The class files will be created under the
 * /core/components/$myPackage/model/
 * directory.
 * Example:
 * $myPackage = 'quotes';
 * $myPrefix = 'bobs_';
 * $path = MODX_CORE_PATH . 'components/' . $myPackage .
       '/';
 * $result = $modx->addPackage($myPackage, $path .
       'model/', $myPrefix);
 * if (! $result) {
 *   return('Failed to add package');
 * }
 */
$myPackage = empty($myPackage)? 'mypackage' : $myPackage;
 
/* table prefix; must match the prefix of the
 * tables you want to process */
$myPrefix = empty ($myPrefix)? '' : $myPrefix;
 
/* Table names to process -- this is only necessary if
 * your table prefix is the same as that of the MODX
 * tables (not recommended). You can send a comma-separated
 * list of full table names. In that case the class name
 * will be the table name minus the prefix with any
 * underscores removed and any letter after an
 * underscore in upper case.
 *
 * You can also send an array of arrays of
 * tableName => className,
 * which allows you to specify the exact class name rather
 * then letting MODX create it from the table name.
 * Each inner array specifies a full table name and the
 * class name to use.
 *
 * NOTE: This feature may not be implemented yet.
 *
 * Examples:
 
$myTables = 'bobs_quotation';
 
$myTables = array(
    array(
        'bobs_quotation'=>'bobQuotation'
    )
);
 
*/
$myTables = empty($myTables)? '' : $myTables;
 
/* You shouldn't need to modify the code beyond this point
******************************************************* */
 
$sources = array(
    'config' => MODX_CORE_PATH . 'config/config.inc.php',
    'package' => MODX_CORE_PATH . 'components/' .
        $myPackage . '/',
    'model' => MODX_CORE_PATH. 'components/' . $myPackage .
        '/model/',
    'schema' => MODX_CORE_PATH . 'components/' .
        $myPackage . '/schema/',
);
 
if (! file_exists($sources['package'])) {
    mkdir($sources['package'],0777);
}
 
if (! file_exists($sources['model'])) {
    mkdir($sources['model'],0777);
}
if (! file_exists($sources['schema'])) {
    mkdir($sources['schema'],0777);
}
 
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
 
$manager = $modx->getManager();
$generator = $manager->getGenerator();
 
if ($includeCustomTemplates) {
    customTemplates($generator);
}
 
 
$file = $sources['schema'] . $myPackage .
    '.mysql.schema.xml';
 
// echo '<br/>File: ' . $file;
 
/* writeSchema() arguments
 * ---------------------------
 * string $schemaFile -- Full path to the schema file
 *     you want to write
 * string $package -- (optional) Name of your component
 * string $baseClass -- (optional) xPDO base class to use;
 *     (send '' if using args below)
 * string $tablePrefix -- Table prefix (of tables to
 *     process)
 * boolean $restrictPrefix) -- (optional) Process only
 * tables with $tablePrefix
 * mixed $tableList -- Array of arrays of
 *    full-table-name=>className or
 *    a string with a comma-separated
 *    list of full table names;
 *    if you send the string the table
 *    name will be used as the class name.
 *
 * returns true on success, false on failure
 */
 
if ($createSchema) {
    $xml= $generator->writeSchema($file,
        $myPackage, '',$myPrefix,true,$myTables);
 
    if ($xml) {
        $modx->log(modX::LOG_LEVEL_INFO,
            'Schema file written to ' . $file);
    } else {
        $modx->log(modX::LOG_LEVEL_INFO,
            'Error writing schema file');
    }
}
 
if ($createClasses) {
    if ($generator->parseSchema($file, $sources['model'])){
        $modx->log(modX::LOG_LEVEL_INFO,
            'Schema file parsed -- Files written to ' .
                $sources['model']);
    } else {
        $modx->log(modX::LOG_LEVEL_INFO,
            'Error parsing schema file');
    }
}
$modx->log(modX::LOG_LEVEL_INFO, 'FINISHED');
exit();
 
function customTemplates($generator) {
$generator->classTemplate= <<<EOD
<?php
/**
 * [+phpdoc-package+]
 * [+phpdoc-subpackage+]
 */
class [[+class]] extends [[+extends]] {
 
}
?>
EOD;
$generator->platformTemplate= <<<EOD
<?php
/**
 * [+phpdoc-package+]
 * [+phpdoc-subpackage+]
 */
require_once (dirname(dirname(__FILE__)) .
    '/[+class-lowercase+].class.php');
class [+class+]_[+platform+] extends [+class+] {
}
?>
EOD;
$generator->mapHeader = <<<EOD
<?php
/**
 * [+phpdoc-package+]
 * [+phpdoc-subpackage+]
 */
EOD;
}


Step 3 :
Create a new ressource called "createXpdoClasses" with no richtext editor and put this code in it :
[[!CreateXpdoClasses? &myPackage=`Version` &myPrefix=`modx_site_content_`]]

-> View the ressource one time in your browser.
-> Delete your "createXpdoClasses" resources and snippet. We do not need them anymore.

Step 4 :
Create a new plugin called "version" on the "onDocFormSave" event. This will increment the version.
<?php
$path = MODX_CORE_PATH . 'components/version/';
$result = $modx->addPackage('Version', $path . 'model/','modx_site_content_');
$currentResource= $modx->getObject('Version', array('contentid' => $id));
    
if (empty($currentResource)) {
    $newResource = $modx->newObject('Version', array(
        'contentid' => $id,
        'version' => 1
    ));
    $newResource->save();
}
else {
    $currentResource->set('version', $currentResource->get('version') + 1);
    $currentResource->save();
}

unset($path, $result, $currentResource, $newResource, $id);


Step 5 :
To get the version on templates and chunks, we will use this little snippet called "getVersion" :
<?php
$result = $modx->query("SELECT version FROM modx_site_content_version WHERE contentid=$id");
$row = $result->fetch(PDO::FETCH_ASSOC);
return $row['version'];
unset($result, $row);


We use it this way in templates :

[[getVersion?id=`[[*id]]`]]


Step 6 :
To generate the version on all existing resources, simply create and run a new snippet "versionAllResources" :
<?php
$resources = $modx->getCollection('modResource', array('class_key'=>'modDocument'));
 
foreach ($resources as $resource) {
    $path = MODX_CORE_PATH . 'components/version/';
    $result = $modx->addPackage('Version', $path . 'model/','modx_site_content_');
    $currentResource= $modx->getObject('Version', array('contentid' => $resource->get('id')));
    
    if (empty($currentResource)) {
        $newResource = $modx->newObject('Version', array(
            'contentid' => $resource->get('id'),
            'version' => 1
        ));
        $newResource->save();
    }
    else {
        $currentResource->set('version', $currentResource->get('version') + 1);
        $currentResource->save();
    }
}
]]>
romainfallet Feb 08, 2016, 09:29 AM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-538044
<![CDATA[Re: Increment a TV on the "onDocFormSave" event. (Best Answer)]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-537975 You could read that value on every OnDocFormSave, incement it, save the incremented value back to your custom-table and to your TV at the same time.

This way the value would really increment on each save.]]>
Bruno17 Feb 06, 2016, 01:24 PM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-537975
<![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-537972
The main reason it's a nightmare is the extJS creates the Manager pages on the fly and the HTML you want to find and modify may not exist at the time you need to access it.

On reflection, most of the JS ideas I had wouldn't actually work. Maybe someone else has an idea.
]]>
BobRay Feb 06, 2016, 01:13 PM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-537972
<![CDATA[Re: Increment a TV on the "onDocFormSave" event.]]> https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-537921 https://forums.modx.com/thread/98798/disable-remove-trash-system-in-modx-revolution

Anyway, I manage PHP in modx but not JS. Where can I put a custom JS script that can access the ressource fields ? Is that about ExtJS ? I've never understood ExtJS and how it works with modx.

Concerning my users, it is not an option, I can only train Pokemons :/]]>
romainfallet Feb 05, 2016, 07:56 AM https://forums.modx.com/thread/99441/increment-a-tv-on-the-ondocformsave-event#dis-post-537921