We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 40447
    • 165 Posts
    If one would like to expand the API for Evo with new api calls, of course you have to know php. But what should be to take care of, not to break anything inside Evo, anyone know of rules or tips for that ?
      • 3749
      • 24,544 Posts
      I'm not sure exactly what you mean by 'expand the API'. Are you thinking of something that couldn't be done with snippets and plugins? Could you give some examples?
        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
        • 40447
        • 165 Posts
        When I read the post about cakephp https://forums.modx.com/index.php?topic=35663.0 I was intrigued how I can expand the API myself in my own personal case.
        Two good examples of very useful API calls that I use in modx are:
        $modx->regClientStartupScript($src);
        $modx->regClientCSS( $myCSS );
        
        Down on this page you can see for example the Function Source of the regClientCSS API:
        http://wiki.modxcms.com/index.php/API:regClientCSS

        API seems to be coded inside this location:
        manager/includes/document.parser.class.inc.php

        Now, if I would make a new API call and add it to the modx core, how would I do that without breaking anything inside modx ?
          • 36416
          • 589 Posts
          Quote from: sitecms at Jan 25, 2013, 03:17 AM
          When I read the post about cakephp https://forums.modx.com/index.php?topic=35663.0Now, if I would make a new API call and add it to the modx core, how would I do that without breaking anything inside modx ?

          By adding methods (object functions) to document parser (MODx) or helper classes (DBAPI...), random examples:
          https://github.com/ClipperCMS/ClipperCMS/commit/4fc8f33319b2f30074a6ef426789ed025f6a4209
          https://github.com/ClipperCMS/ClipperCMS/commit/e06d1c27928c81229a6202b8ed360190193d2779
            • 40447
            • 165 Posts
            Thanks for those links Eoler. Examples are always a good place to start with. If anyone knows of more examples, please post.
              • 4310
              • 2,310 Posts
              Although I'm sure it's not recommended and if you don't mind making a small hack in the manager/includes/document.parser.class.inc.php file it is quire easy to add your own custom API.
              Change at around line 50 of document.parser.class.inc.php :
               // constructor
                  function DocumentParser() {
                      $this->loadExtension('DBAPI') or die('Could not load DBAPI class.'); // load DBAPI class
                      $this->loadExtension('CustomAPI') or die('Could not load CustomAPI class.'); // load CustomAPI class
                      $this->dbConfig= & $this->db->config; // alias for backward compatibility
                      $this->jscripts= array ();
                      $this->sjscripts= array ();
                      $this->loadedjscripts= array ();
                      // events
                      $this->event= new SystemEvent();
                      $this->Event= & $this->event; //alias for backward compatibility
                      $this->pluginEvent= array ();
                      // set track_errors ini variable
                      @ ini_set("track_errors", "1"); // enable error tracking in $php_errormsg
                  }
              
                  // loads an extension from the extenders folder
                  function loadExtension($extname) {
                      global $database_type;
              
                      switch ($extname) {
                          // Database API
                          case 'DBAPI' :
                              if (!include_once MODX_BASE_PATH . 'manager/includes/extenders/dbapi.' . $database_type . '.class.inc.php')
                                  return false;
                              $this->db= new DBAPI;
                              return true;
                              break;
              
                              // Manager API
                          case 'ManagerAPI' :
                              if (!include_once MODX_BASE_PATH . 'manager/includes/extenders/manager.api.class.inc.php')
                                  return false;
                              $this->manager= new ManagerAPI;
                              return true;
                              break;
                              
                              // CustomAPI
                          case 'CustomAPI' :
                              if (!include_once MODX_BASE_PATH . 'manager/includes/extenders/custom.api.class.inc.php')
                                  return false;
                              $this->custom= new CustomAPI;
                              return true;
                              break;
              
                          default :
                              return false;
                      }
                  }

              So now we have our extension loading and being included, we need our manager/includes/extenders/custom.api.class.inc.php
              The one below is just a demo and has no particularly useful functions :
              <?php
              class CustomAPI {
              	var $customId; 
              	var $customClass;
              	var $customLink;
              	var $customQuery;
              	var $customQueryValue;
              			
              		function setCustomClass($customClass) {
              		$this->customClass = $customClass ? $customClass : 'my-class';
              		return ' class="'.$this->customClass.'" ';
              		}
              
              		function setCustomQuery($customQuery) {
              		$this->customQuery = $customQuery ? $customQuery : 'searching';
              		return $this->customQuery;
              		}
              		
              		function setCustomQueryValue($customQueryValue) {
              		$this->customQueryValue = $customQueryValue ? $customQueryValue : 'something';
              		return '='.$this->customQueryValue;
              		}
              	
              		function setCustomId($customId,$customQuery,$customQueryValue){
              		global $modx;
              		$this->customId = $customId ? $customId : 1;
              		$url = $modx->makeUrl($this->customId,'',$this->setCustomQuery($customQuery) . $this->setCustomQueryValue($customQueryValue), 'full');
              		return ' href="'.$url.'"';
              		}
              	
              		function setCustomLink($customLink){
              		$this->customLink = $customLink ? $customLink : 'link text here';
              		return $this->customLink;
              		}
              		
              		function setCustomOutput($customClass,$customId,$customLink,$customQuery,$customQueryValue) {
              		$o .= '<a';
              		$o .= $this->setCustomId($customId,$customQuery,$customQueryValue);
              		$o .= $this->setCustomClass($customClass);
              		$o .= '>';
              		$o .= $this->setCustomLink($customLink);
              		$o .= '</a>';
              		return $o;
              	}
              	
              }
              ?>

              Finally a snippet to do something with the newly extended API :
              <?php
              /*
              $text = $modx->custom->setCustomOutput('link class name', 'document id', 'link text', 'querystring name', 'querystring value');
              defaults set in cusom api class are => ('my-class', '1', 'link text here', 'searching', 'something');
              gives output of <a href="http://localhost/development/index.html?searching=something" class="my-class">link text here</a>
              */
              $text = $modx->custom->setCustomOutput('','' ,'','','');
              return $text;
              ?>

              More of a proof of concept than something instantly usable, but it seems to work okay.
              Obviously you'd loose the edits in the document.parser.class.inc.php in an upgrade so a backup needs to be made.
              There may be some impact on performance, particularly if your own custom API is large or demanding.
                • 28042 ☆ A M B ☆
                • 24,524 Posts
                You are free to include any files you want in snippets or plugins. For example, the WebLoginPE snippet is a complete user management package with its own API. Or you can include your file and instantiate your object in a plugin that uses the appropriate parser 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
                  • 40447
                  • 165 Posts
                  Thanks bunk58 for both the api with snippet example, and susan for make use of snippets and plugins. The links from bunk58 also leaded (at least for me) to
                  2 great finds: http://wiki.modxcms.com/index.php/DB_query_and_Placeholders and http://www.plohni.com/wb/content/php/Tutorials.php (php tutorials)