We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 3467
    • 10 Posts
    I’m fairly new on both Modx and PHP, and I might be stupid, but I have some custom functions that I’ve tried to execute whenever content is saved in manager. Just to try it out I’ve included my class in save_content.processor.php, and try to execute a function:

    require_once ’my.class.php’;
    MyClass::create();

    The function call comes in the beginning of save_content.processor.php, but obviously I’m doing something wrong, ’cause nothing happens. Any suggestions would be appreciated smiley



      • 28042 ☆ A M B ☆
      • 24,524 Posts
      This is what plugins are for. There are a number of "events" that are available for using to insert your own custom functionality at that point in the core processing. If you look at the save_content.processor file, you’ll see what events are available. Using a plugin, you won’t need to hack the core files.

      Plugins aren’t very heavily documented, but there are plenty of existing plugins to look at for examples; basically it’s just a matter of determining which event would be the best for your purpose, putting your code in the plugin and checking the desired event.

        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 3467
        • 10 Posts
        Great, just what I was looking for really. Thanks.

        Followup question:

        "OnDocFormSave" and "OnDocFormDelete" are two events I need to use, but I would also need to check on "undelete" and "publish/unpublish" events. I can’t find which events to look for in my plugin... are there any?


          • 22797
          • 134 Posts
          There are several events that are missing from the core code right now. I’ve created patches and uploaded them in the bug reporting software for MODx, but no one seems to be acting on them, so I don’t know when or if they’ll do anything about it. Here are the links to my posts and patches (you’ll need to log in to the bug tracker):

          http://svn.modxcms.com/jira/browse/MODX-189
          http://svn.modxcms.com/jira/browse/MODX-308
          http://svn.modxcms.com/jira/browse/MODX-312
          http://svn.modxcms.com/jira/browse/MODX-313

          These are modifications to certain core files. They add the triggers you’re looking for. Of course, if the people at MODx don’t incorporate these fixes into the code in future releases, you’ll have to add similar patches to those future releases. So far I haven’t gotten any feedback or acknowledgment from the MODx group about my updates, but I can verify that the patches do work. I have been using them successfully, with no negative effect, at least in my testing.
            • 25663 MODX Staff
            • 12,272 Posts
            Thanks for consolidating those into a single post Paul and bringing it up here. I’ve taken the liberty to convert them into a single enhancement task in Jira: http://svn.modxcms.com/jira/browse/MODX-343

            While they won’t make it into the next/immediate 0.9.6.2 release, I can say that they certainly make sense for Evolution. Evolution will be in essence a streamlined and less bloated version of modx that you see today that adopts some of the nomenclature and conventions of Revolution. Hopefully 0.9.6.2 will be our last "legacy" release unless some outrageous issue crops up meaning 0.9.6.3 should be released as well.

            Thanks again!


              Ryan Thrash, MODX Co-Founder
              Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
              • 22797
              • 134 Posts
              Thanks for taking a look at those issues! Another related issue that I’ve run into while using those events, and which I would love to see resolved, is the current inability in the API to retrieve all documents -- with their associated document object arrays -- irrespective of publication or deletion status. The only way to get all documents now is by creating separate queries for each condition. And there is no way at all of retrieving a document object array for deleted objects using the MODx API  (unless there’s another way that I’m missing).

              I posted a patch for these issues here: http://svn.modxcms.com/jira/browse/MODX-322

              The changes are very minor, but they make a big difference in what I’m able to do with the various events.
                • 25663 MODX Staff
                • 12,272 Posts
                Paul, do you have actual patches for the changes you suggested or just full updated files (at least in the case of 322, which is the last one I peeked at)? It would be very helpful to have them in that format according to the powers that be, and attached to their respective tasks. Thanks.
                  Ryan Thrash, MODX Co-Founder
                  Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
                  • 22797
                  • 134 Posts
                  At the moment I only have the full updated files, but I can prepare the changes in some other format. I guess I don’t know what officially constitutes a "patch" vs. an updated file. If you swap out the existing files with the ones I supplied, that will "patch" them, but obviously you’re looking for something different. Let me know what you want and I’ll prepare it that way.
                    • 22797
                    • 134 Posts
                    I’ve highlighted the changes that I made to document.parser.class.php below (I’m showing only the affected functions):

                    function getDocuments($ids= array (), $published= 1, $deleted= 0, $fields= "*", $where= ’’, $sort= "menuindex", $dir= "ASC", $limit= "") {
                    if (count($ids) == 0) {
                    return false;
                    } else {
                    $limit= ($limit != "") ? "LIMIT $limit" : ""; // LIMIT capabilities - rad14701
                    $tblsc= $this->getFullTableName("site_content");
                    $tbldg= $this->getFullTableName("document_groups");
                    // modify field names to use sc. table reference
                    $fields= ’sc.’ . implode(’,sc.’, preg_replace("/^\s/i", "", explode(’,’, $fields)));
                    $sort= ($sort == "") ? "" : ’sc.’ . implode(’,sc.’, preg_replace("/^\s/i", "", explode(’,’, $sort)));
                    if ($where != ’’)
                    $where= ’AND ’ . $where;
                    // get document groups for current user
                    if ($docgrp= $this->getUserDocGroups())
                    $docgrp= implode(",", $docgrp);
                    $access= ($this->isFrontend() ? "sc.privateweb=0" : "1=’" . $_SESSION[’mgrRole’] . "’ OR sc.privatemgr=0") .
                    (!$docgrp ? "" : " OR dg.document_group IN ($docgrp)");
                    // Ability to get all documents, whether deleted or unpublished, added by Paul Bohman
                    if ($published == ’*’) $sqlPublished = ’’;
                    else $sqlPublished = "AND sc.published=$published";
                    if ($deleted == ’*’) $sqlDeleted = ’’;
                    else $sqlDeleted = "AND sc.deleted=$deleted";
                    // end added code

                    $sql= "SELECT DISTINCT $fields FROM $tblsc sc
                    LEFT JOIN $tbldg dg on dg.document = sc.id
                    WHERE (sc.id IN (" . join($ids, ",") . ") $sqlPublished $sqlDeleted $where) // code altered here
                    AND ($access)
                    GROUP BY sc.id " .
                    ($sort ? " ORDER BY $sort $dir" : "") . " $limit ";
                    // end altered code
                    $result= $this->dbQuery($sql);
                    $resourceArray= array ();
                    for ($i= 0; $i < @ $this->recordCount($result); $i++) {
                    array_push($resourceArray, @ $this->fetchRow($result));
                    }
                    return $resourceArray;
                    }
                    }

                    And here’s the next one:

                    function getTemplateVars($idnames= array (), $fields= "*", $docid= "", $published= 1, $sort= "rank", $dir= "ASC",$deleted=0) {
                    // The ’deleted’ option was added by Paul Bohman
                    if (($idnames != ’*’ && !is_array($idnames)) || count($idnames) == 0) {
                    return false;
                    } else {
                    $result= array ();

                    // get document record
                    if ($docid == "") {
                    $docid= $this->documentIdentifier;
                    $docRow= $this->documentObject;
                    } else {
                    $docRow= $this->getDocument($docid, ’*’, $published,$deleted); // code altered here
                    if (!$docRow)
                    return false;
                    }

                    // get user defined template variables
                    $fields= ($fields == "") ? "tv.*" : ’tv.’ . implode(’,tv.’, preg_replace("/^\s/i", "", explode(’,’, $fields)));
                    $sort= ($sort == "") ? "" : ’tv.’ . implode(’,tv.’, preg_replace("/^\s/i", "", explode(’,’, $sort)));
                    if ($idnames == "*")
                    $query= "tv.id<>0";
                    else
                    $query= (is_numeric($idnames[0]) ? "tv.id" : "tv.name") . " IN (’" . implode("’,’", $idnames) . "’)";
                    if ($docgrp= $this->getUserDocGroups())
                    $docgrp= implode(",", $docgrp);
                    $sql= "SELECT $fields, IF(tvc.value!=’’,tvc.value,tv.default_text) as value ";
                    $sql .= "FROM " . $this->getFullTableName(’site_tmplvars’)." tv ";
                    $sql .= "INNER JOIN " . $this->getFullTableName(’site_tmplvar_templates’)." tvtpl ON tvtpl.tmplvarid = tv.id ";
                    $sql .= "LEFT JOIN " . $this->getFullTableName(’site_tmplvar_contentvalues’)." tvc ON tvc.tmplvarid=tv.id AND tvc.contentid = ’" . $docid . "’ ";
                    $sql .= "WHERE " . $query . " AND tvtpl.templateid = " . $docRow[’template’];
                    if ($sort)
                    $sql .= " ORDER BY $sort $dir ";
                    $rs= $this->dbQuery($sql);
                    for ($i= 0; $i < @ $this->recordCount($rs); $i++) {
                    array_push($result, @ $this->fetchRow($rs));
                    }

                    // get default/built-in template variables
                    ksort($docRow);
                    foreach ($docRow as $key => $value) {
                    if ($idnames == "*" || in_array($key, $idnames))
                    array_push($result, array (
                    "name" => $key,
                    "value" => $value
                    ));
                    }

                    return $result;
                    }
                    }


                    And here’s the next one:
                    function getTemplateVarOutput($idnames= array (), $docid= "", $published= 1,$deleted=0) {
                    // The ’deleted’ option was added by Paul Bohman
                    if (count($idnames) == 0) {
                    return false;
                    } else {
                    $output= array ();
                    $vars= ($idnames == ’*’ || is_array($idnames)) ? $idnames : array ($idnames);
                    $docid= intval($docid) ? intval($docid) : $this->documentIdentifier;
                    $result= $this->getTemplateVars($vars, "*", $docid, $published, "", "",$deleted); // remove sort for speed
                    // The ’deleted’ option was added above by Paul Bohman
                    if ($result == false)
                    return false;
                    else {
                    $baspath= $this->config["base_path"] . "manager/includes";
                    include_once $baspath . "/tmplvars.format.inc.php";
                    include_once $baspath . "/tmplvars.commands.inc.php";
                    for ($i= 0; $i < count($result); $i++) {
                    $row= $result[$i];
                    // to-do needs fixing when getting tvs from other pages
                    $replace_richtext= "";
                    $richtexteditor= "";
                    $w= "100%";
                    $h= "300";
                    $output[$row[’name’]]= getTVDisplayFormat($row[’name’], $row[’value’], $row[’display’], $row[’display_params’], $row[’type’], $docid);
                    }
                    return $output;
                    }
                    }
                    }

                    Hope this helps.
                      • 25663 MODX Staff
                      • 12,272 Posts
                      Quote from: paulb at Sep 14, 2008, 03:46 PM

                      At the moment I only have the full updated files, but I can prepare the changes in some other format. I guess I don’t know what officially constitutes a "patch" vs. an updated file. If you swap out the existing files with the ones I supplied, that will "patch" them, but obviously you’re looking for something different. Let me know what you want and I’ll prepare it that way.

                      If we’ve made other changes in the interim to those files, and blindly swap them out, then those other changes would be lost. A patch file shows the diffs and allows you to update very specific sections of code.

                      http://en.wikipedia.org/wiki/Patch_(Unix)
                        Ryan Thrash, MODX Co-Founder
                        Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me