We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 7966
    • 90 Posts
    I am trying to use autolink module/plugin in Revo, actually only the plugin part. I copied the code but I do get an error which states that "Call to undefined function autolink() ". This is a function inside the plugin code itself.

    Maybe it was possible in Evo but not possible in Revo anymore. Is it possible to create a php function inside the plugin element and use it in REVO? Any ideas?

    Thank you
      • 3749
      • 24,544 Posts
      It should work fine. Can you post your plugin code?
        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
        • 7966
        • 90 Posts
        actually it is the exact code from autolink, which is below
        <?php
        /** 
         * Autolink plugin
         * 
         * Author: Garry Nutting
         * Original Code and Concept: phpGiggle by Biermana
         * 
         * Version: 1.1
         * Date: 03/05/06
         * 
         * CSS Styles:
         * 
         * autolink_highlight
         * autolink_link
         * autolink_abbr
         * autolink_acro
         * autolink (for Google, CPAN etc. - can be changed in respective function)
         * 
         * updated: support for accented characters
         */
        
        //-- set the template function target
        //-- use with externalLinks js function to open template function links in new window
        //-- http://pure-essence.net/archives/2006/02/02/relexternal/
        define('autolink_target', 'rel="external"');
        
        $e = & $modx->Event;
        switch ($e->name) {
        	case "OnWebPagePrerender" :
        		//-- get current template value
        	    $table = $modx->getFullTableName('site_content');
        		$sql = $modx->db->select('template', $table, 'id="' . $modx->documentIdentifier . '"');
        		$row = $modx->db->getRow($sql);
        		//-- do not run if on blank template (so it doesn't interfere with RSS feeds)
        		if ($row['template'] <> 0) {
        			$pg = & $modx->documentOutput;
        			$pg = autolink($pg);
                                
        		} else {
        			return $modx->documentOutput;
        		}
        		break;
        	default :
        		return;
        		break;
        }
        
        /*
         * Main autolink function - replaces keywords with desired values
         */
        function autolink($string) {
        	global $modx;
        
        	//-- replace with match (1) or value entered in table (0)
        	$match_replace = 1;
        
        	//-- blocked tags ie. those that the tokenizer will ignore
        	$blocked_tags = 'code|pre';
        
        	//-- validation regexes uses in function
        	$valid_key_regexp = "[^\w\.\_\-\:\s]"; // valid keyword
        	$valid_html_color = "^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$"; // matches HTML octal color identifier
        	$valid_url_regexp = "^(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\." .
        	"(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}" .
        	"[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|" .
        	"[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$"; // validates a URL
        
        	$autolinkValue = array (); //-- stores the link values
        	$autolinkTitle = array (); //-- stores the title attribute values
        	$autolinkDefault = array (); //-- will store the abbreviation/acronym value
        
        	//-- setup db table name
        	$autolinkTable = $modx->getFullTableName('autolinkwords');
        
        	//-- get keywords from db
        	$rs = $modx->db->select('*', $autolinkTable);
        
        	//if no keywords in table, then exit now
        	if ($modx->db->getRecordCount($rs) == 0) {
        		return $string;
        	}
        
        	while ($row = $modx->db->getRow($rs)) {
        		$temp_word = $row['keyword'];
        		$autolinkValue[$row['keyword']] = $row['link'];
        		$autolinkTitle[$row['keyword']] = $row['title'];
        		$autolinkDefault[$row['keyword']] = $row['default_type'];
        	}
        
        	//-- get the body tags
        	preg_match('/(<body.*?>)/', $string, $open);
        	preg_match('/(<\/body.*?>)/', $string, $close);
        	$body_open = $open[1];
        	$body_close = $close[1];
        
        	unset ($open);
        	unset ($close);
        
        	//-- get only body html - will add head and footer back in later
        	$temp = explode("$body_open", $string);
        	$head = $temp[0];
        	$string = $temp[1];
        	$temp = explode("$body_close", $string);
        	$string = $temp[0];
        	$footer = $temp[1];
        
        	//-- ensure that first autolink match will always be second entry in array
        	$text = " $string ";
        
        	//-- split the content around the <autolink> tags
        	$textarr = preg_split("/<autolink>(.*)<\/autolink>/Us", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
        	//-- setup output string
        	$out = '';
        
        	//-- start main loop of content array
        	for ($i = 0; $i < count($textarr); $i++) {
        		$text = $textarr[$i];
        
        		//-- skip the entries outside autolink tags
        		if ($i % 2 == 0) {
        			$out .= $text;
        			continue;
        		}
        
        		//-- loop through each keyword in the array
        		foreach ($autolinkValue as $keyword => $link) {
        
        			//-- get other keyword values
        			$title = $autolinkTitle[$keyword];
        			$default = $autolinkDefault[$keyword];
        
        			//-- setup the tokenizer variables
        			$anchor_level = 0;
        			$tag_level = 0;
        			$must_tokenize = TRUE; //-- will perform basic tokenization
        			$tokens = NULL; //-- two kinds of tokens: markup and text
        
        			$filtered = ''; //-- will filter text token by token
        
        			$match = "/\b" . preg_quote(htmlentities($keyword), "/") . "\b/i"; //-- check for encoded match
        			$match_noencode = "/\b" . preg_quote($keyword, "/") . "\b/i"; //-- check for non-encoded match
        
        			switch ($link) {
        				//-- autolink template functions
        				case function_exists("autolink_" . $link) :
        					$autolink_function = "autolink_" . $link;
        					$substitute = $autolink_function ($keyword);
        					break;
        					//-- highlight
        				case (eregi("$valid_html_color", $link) ? $link : !$link) :
        					$substitute = '<span class="autolink_highlight" title="' . $title . '" style="background-color:' . $link . ';">' . htmlentities($keyword) . '</span>';
        					break;
        					//-- just link
        				case (eregi("$valid_url_regexp", $link) ? $link : !$link) :
        					$substitute = '<a class="autolink_link" href="' . $link . '" title="' . $title . '">' . htmlentities($keyword) . '</a>';
        					break;
        					//-- Acronym or just alt-text
        				default :
        					//-- be smart about whether a title has been passed or not
        					$title = ($title <> '') ? $title : $link;
        					if ($default == 0) {
        						$substitute = '<abbr title="' . $title . '"><span class="autolink_abbr" title="' . $title . '">' . htmlentities($keyword) . '</span></abbr>';
        					} else {
        						$substitute = '<acronym class="autolink_acro" title="' . $title . '">' . htmlentities($keyword) . '</acronym>';
        					}
        					break;
        			}
        			if ($must_tokenize) // for efficiency only tokenize if forced to do so
        				{
        				//-- this regexp is taken from PHP Markdown by Michel Fortin:
        				//-- http://www.michelf.com/projects/php-markdown/
        				$comment = '(?s:<!(?:--.*?--\s*)+>)|';
        				$processing_instruction = '(?s:<\?.*?\?>)|';
        				$tag = '(?:<[/!$]?[-a-zA-Z0-9:]+\b(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*>)';
        				$markup = $comment . $processing_instruction . $tag;
        				$flags = PREG_SPLIT_DELIM_CAPTURE;
        				$tokens = preg_split("{($markup)}", $text, -1, $flags);
        				$must_tokenize = FALSE;
        			}
        
        			//-- there should always be at least one token, but check just in case
        			if (isset ($tokens) && is_array($tokens) && count($tokens) > 0) {
        				$j = 0;
        				foreach ($tokens as $token) {
        					if (++ $j % 2 && $token != '') //-- this token is (non-markup) text
        						{
        						if ($anchor_level == 0 && $tag_level == 0) // linkify if not inside anchor tags
        							{
        
        							//-- test for encoded keyword
        							if (preg_match($match, $token, $kmatch)) {
        								//-- ensure that the substitute replaces value with the case-sensitive match
        								if ($match_replace == 1) {
        									$substitute = preg_replace('/\b' . htmlentities($keyword) . '\b/', $kmatch[0], $substitute);
        								}
        								//-- replace keyword with the substitute
        								$token = preg_replace($match, $substitute, $token);
        								$must_tokenize = TRUE; //-- re-tokenize next time around						
        
        								//-- test for non-encoded keyword
        							}
        							elseif (preg_match($match_noencode, $token, $kmatch)) {
        								//-- ensure that the substitute replaces value with the case-sensitive match
        								if ($match_replace == 1) {
        									$substitute = preg_replace('/\b' . $keyword . '\b/', $kmatch[0], $substitute);
        								}
        								//-- replace keyword with the substitute
        								$token = preg_replace($match_noencode, $substitute, $token);
        								$must_tokenize = TRUE; //-- re-tokenize next time around
        							}
        						}
        
        					} else //-- this token is markup
        						{
        						if (preg_match("#<\s*a\s+[^>]*>#i", $token)) { //-- found <a ...>
        							$anchor_level++;
        						}
        						elseif (preg_match("#<\s*/\s*a\s*>#i", $token)) { //-- found </a>
        							$anchor_level--;
        						}
        						elseif (preg_match("#<($blocked_tags)>#i", $token)) { //-- found excluded tags
        							$tag_level++;
        						}
        						elseif (preg_match("#<\/($blocked_tags)>#i", $token)) { //-- found excluded closing tags
        							$tag_level--;
        						}
        					}
        					$filtered .= $token; //-- this token has now been filtered
        				}
        			}
        			$text = $filtered; //-- filtering completed for this link
        		}
        		//-- add section to the output
        		$out .= $text;
        	}
        	//-- return the compiled output to the browser
        	return $head . $body_open . trim($out) . $body_close . $footer;
        }
        
        /******************************************************************
         * 
         * Template Functions
         * 
         */
        
        /*
            template function for search.cpan.org
        */
        
        function autolink_cpan($autolink_it) {
        	return "<a " . autolink_target . " class=\"autolink\" title=\"Search CPAN for '" .
        	$autolink_it . "' !\" href=\"http://search.cpan.org/search?query=" . urlencode($autolink_it) . "\">" .
        	$autolink_it . "</a>";
        }
        
        /*
            template function for google.com
        */
        function autolink_google($autolink_it) {
        	return "<a " . autolink_target . " class=\"autolink\" title=\"Google.com search for '" .
        	$autolink_it . "' !\" href=\"http://www.google.com/search?q=" . $autolink_it . "\">" .
        	$autolink_it . "</a>";
        }
        
        /*
            template function for dictionary.com
        */
        function autolink_dictionary($autolink_it) {
        	return "<a " . autolink_target . " class=\"autolink\" title=\"Dictionary.com definition for '" .
        	$autolink_it . "' !\" href=\"http://dictionary.reference.com/search?q=" . $autolink_it . "\">" .
        	$autolink_it . "</a>";
        }
        
        /*
            template function for freshmeat.net
        */
        function autolink_freshmeat($autolink_it) {
        	return "<a " . autolink_target . " class=\"autolink\" title=\"Freshmeat.net search projects for '" .
        	$autolink_it . "' !\" href=\"http://freshmeat.net/search/?q=" . urlencode($autolink_it) . "\">" .
        	$autolink_it . "</a>";
        }
        
        /*
            template function for vivisimo.com
        */
        function autolink_vivisimo($autolink_it) {
        	return "<a " . autolink_target . " class=\"autolink\" title=\"Vivisimo.com document cluster for '" .
        	$autolink_it . "' !\" href=\"http://www.vivisimo.com/search?query=" . urlencode($autolink_it) . "\">" .
        	$autolink_it . "</a>";
        }
        
        /*
            template function for webopedia.com
            note:  no gaurantee the webopedia page exists - better to manually check it first
        */
        function autolink_webopedia($autolink_it) {
        	return "<a " . autolink_target . " class=\"autolink\" title=\"Webopedia.com definition for '" .
        	$autolink_it . "' !\" href=\"http://www.webopedia.com/TERM/" . substr($autolink_it, 0, 1) . "/" . str_replace(" ", "_", $autolink_it) . ".html" . "\">" .
        	$autolink_it . "</a>";
        }
        
        

          • 26903
          • 1,336 Posts
          You have a syntax error on line 91,
          //-- get the body tags
          preg_match(/(<body.*?>)/', $string, $open);
          


          needs an opening ’ as in preg_match(’/(<body.*?>)/’, $string, $open);
            Use MODx, or the cat gets it!
            • 7966
            • 90 Posts
            Thanks shamblett.

            Checked the code, but it has opening ’ in the original code and the code my plugin code but I don’t know why it is removed when I paste the code.

            the code on that line is

            preg_match(’/(<body.*?>)/’, $string, $open);

            I cleaned all the code inside autolink function, also the beginning code, just added an echo , I still get the same error with the following simple code.

            <?php
            
            $pg = 'ABC';
            $pg = autolink($pg);
            
            function autolink($string) {
            	echo 'HELLO';
            }
              • 3749
              • 24,544 Posts
              That’s an odd one. Are you using CodeMirror by any chance? It sometimes leaves invisible characters in the file.

              If not, the only thing I can suggest is retyping the lines with "autolink" in them from scratch in case there’s an extraneous non-visible character in the name somewhere.

              You might also try manually deleting all the files in the core/cache dir. except index.php and clear your browser cache, to make absolutely sure you’re not running a cached version of the plugin.
                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
                • 7966
                • 90 Posts
                Thanks BobRay.

                I don’t use codemirror.

                I deleted the code, and wrote a new one, cleared the modx cache and browser cache, I checked the core/cache/elements/modplugin directory, it actually has the last code in cache files, but still getting the error with following code.
                <?php
                
                test();
                
                function test(){
                 echo 'testing...';
                }



                weird problem. any suggestions to try a workaround to this problem
                  • 3749
                  • 24,544 Posts
                  Putting the code in a snippet generates the same error.

                  Putting the function above the function call fixes it. In PHP3, functions had to be defined before they were used. I don’t know why this would be happening now.

                  <?php
                  
                  function test(){
                   echo 'testing...';
                  
                  test();
                  
                  }
                    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
                    • 7966
                    • 90 Posts
                    I am new to php, so that would be last thing I would try. It is working now as you said.

                    Thanks a lot BobRay for your help.