예제 #1
0
 /**
  * Describe a service and all its methods
  * @param $data An object containing 'label' and 'data' keys
  */
 public function describeService($data)
 {
     $className = $data['label'];
     //Sanitize path
     //$path = str_replace('..', '', $data['data']);
     $methodTable = MethodTable::create($this->servicePath . ($data['data'] ? DIRECTORY_SEPARATOR . $data['data'] : '') . $className . '.php', NULL, $classComment);
     return array($methodTable, $classComment);
 }
예제 #2
0
 /**
  * Describe a service and all its methods
  * @param $data An object containing 'label' and 'data' keys
  */
 function describeService($data)
 {
     $className = $data['label'];
     //Sanitize path
     $path = str_replace('..', '', $data['data']);
     //Generate the method table from this info
     $this->_path = dirname(dirname(realpath(__FILE__))) . DIRECTORY_SEPARATOR;
     $methodTable = MethodTable::create($this->_path . $path . $className . '.php', NULL, $classComment);
     return array($methodTable, $classComment);
 }
예제 #3
0
/**
 * Parse a file to find out what functions/methods exist in it, and add entries
 * for the remote-call-enabled functions to the database.
 *
 * The path to a file, e.g. auth/mnet/auth.php can be thought of as
 * type/parentname/docname
 *
 * @param  string   $type           mod, auth or enrol
 * @param  string   $parentname     Implementation of type, e.g. 'mnet' in the
 *                                  case of auth/mnet/auth.php
 * @return bool                     True on success, else false
 */
function mnet_get_functions($type, $parentname)
{
    global $CFG;
    $dataobject = new stdClass();
    $docname = $type . '.php';
    $publishes = array();
    if ('mod' == $type) {
        $docname = 'rpclib.php';
        $relname = '/mod/' . $parentname . '/' . $docname;
        $filename = $CFG->dirroot . $relname;
        if (file_exists($filename)) {
            include_once $filename;
        }
        $mnet_publishes = $parentname . '_mnet_publishes';
        if (function_exists($mnet_publishes)) {
            (array) ($publishes = $mnet_publishes());
        }
    } elseif ('local' == $type) {
        $docname = 'rpclib.php';
        $relname = '/local/' . $parentname . '/' . $docname;
        $filename = $CFG->dirroot . $relname;
        if (file_exists($filename)) {
            include_once $filename;
        }
        $mnet_publishes = $parentname . '_mnet_publishes';
        if (function_exists($mnet_publishes)) {
            (array) ($publishes = $mnet_publishes());
        }
    } else {
        // auth or enrol
        $relname = '/' . $type . '/' . $parentname . '/' . $docname;
        $filename = $CFG->dirroot . $relname;
        if (file_exists($filename)) {
            include_once $filename;
        }
        $class = $type . ($type == 'enrol' ? 'ment' : '') . '_plugin_' . $parentname;
        if (class_exists($class)) {
            $object = new $class();
            if (method_exists($object, 'mnet_publishes')) {
                (array) ($publishes = $object->mnet_publishes());
            }
        }
    }
    $methodServiceArray = array();
    foreach ($publishes as $service) {
        if (is_array($service['methods'])) {
            foreach ($service['methods'] as $methodname) {
                $methodServiceArray[$methodname][] = $service;
            }
        }
    }
    // Disable functions that don't exist (any more) in the source
    // Should these be deleted? What about their permissions records?
    $rpcrecords = get_records_select('mnet_rpc', ' parent=\'' . $parentname . '\' AND parent_type=\'' . $type . '\' ', 'function_name ASC ');
    if (!empty($rpcrecords)) {
        foreach ($rpcrecords as $rpc) {
            if (!array_key_exists($rpc->function_name, $methodServiceArray)) {
                $rpc->enabled = 0;
                update_record('mnet_rpc', $rpc);
            }
        }
    }
    if (!file_exists($filename)) {
        return false;
    }
    if (extension_loaded('tokenizer')) {
        include_once "{$CFG->dirroot}/{$CFG->admin}/mnet/MethodTable.php";
        $functions = (array) MethodTable::create($filename, false);
    }
    foreach ($methodServiceArray as $method => $servicearray) {
        if (!empty($functions[$method])) {
            $details = $functions[$method];
            $profile = $details['arguments'];
            if (!isset($details['returns'])) {
                array_unshift($profile, array('type' => 'void', 'description' => 'No return value'));
            } else {
                array_unshift($profile, $details['returns']);
            }
            $dataobject->profile = serialize($profile);
            $dataobject->help = addslashes($details['description']);
        } else {
            $dataobject->profile = serialize(array(array('type' => 'void', 'description' => 'No return value')));
            $dataobject->help = '';
        }
        $dataobject->function_name = $method;
        $dataobject->xmlrpc_path = $type . '/' . $parentname . '/' . $docname . '/' . $method;
        $dataobject->parent_type = $type;
        $dataobject->parent = $parentname;
        $dataobject->enabled = '0';
        if ($record_exists = get_record('mnet_rpc', 'xmlrpc_path', $dataobject->xmlrpc_path)) {
            $dataobject->id = $record_exists->id;
            $dataobject->enabled = $record_exists->enabled;
            update_record('mnet_rpc', $dataobject);
        } else {
            $dataobject->id = insert_record('mnet_rpc', $dataobject, true);
        }
        foreach ($servicearray as $service) {
            $serviceobj = get_record('mnet_service', 'name', $service['name']);
            if (false == $serviceobj) {
                $serviceobj = new stdClass();
                $serviceobj->name = $service['name'];
                $serviceobj->apiversion = $service['apiversion'];
                $serviceobj->offer = 1;
                $serviceobj->id = insert_record('mnet_service', $serviceobj, true);
            }
            if (false == get_record('mnet_service2rpc', 'rpcid', $dataobject->id, 'serviceid', $serviceobj->id)) {
                $obj = new stdClass();
                $obj->rpcid = $dataobject->id;
                $obj->serviceid = $serviceobj->id;
                insert_record('mnet_service2rpc', $obj, true);
            }
        }
    }
    return true;
}
예제 #4
0
 /**
  * Creates the methodTable for a passed class.
  *
  * @static
  * @access public
  * @param $className(String) The name of the service class.
  *        May also simply be __FILE__
  * @param $servicePath(String) The location of the classes (optional)
  */
 function create($className, $servicePath = NULL, &$classComment)
 {
     $methodTable = array();
     if (file_exists(Inflector::underscore($className))) {
         //The new __FILE__ way of doing things was used
         // Files are underscored in cakePHP
         $sourcePath = Inflector::underscore($className);
         $className = str_replace("\\", '/', $className);
         $className = substr($className, strrpos($className, '/') + 1);
         // Class names are CamelCased in cakePHP
         $className = Inflector::camelize(str_replace('.php', '', $className));
     } else {
         $className = str_replace('.php', '', $className);
         $fullPath = Inflector::underscore(str_replace('.', '/', $className));
         $className = Inflector::camelize($fullPath);
         if (strpos($fullPath, '/') !== FALSE) {
             // Class names are CamelCased in cakePHP
             $className = Inflector::camelize(substr(strrchr($fullPath, '/'), 1));
         }
         if ($servicePath == NULL) {
             if (isset($GLOBALS['amfphp']['classPath'])) {
                 $servicePath = $GLOBALS['amfphp']['classPath'];
             } else {
                 $servicePath = "../services/";
             }
         }
         $sourcePath = $servicePath . $fullPath . ".php";
     }
     if (!file_exists($sourcePath)) {
         trigger_error("The MethodTable class could not find {" . $sourcePath . "}", E_USER_ERROR);
     }
     if (class_exists('ReflectionClass')) {
         //PHP5
         $classMethods = MethodTable::getClassMethodsReflection($sourcePath, $className, $classComment);
     } else {
         //PHP4
         $classMethods = MethodTable::getClassMethodsTokenizer($sourcePath, $className, $classComment);
     }
     foreach ($classMethods as $key => $value) {
         if ($value['name'][0] == '_' || $value['name'] == 'beforeFilter') {
             continue;
         }
         if (defined("METHOD_PREFIX")) {
             if (METHOD_PREFIX != substr($value['name'], 0, strlen(METHOD_PREFIX))) {
                 continue;
             }
         }
         $methodSignature = $value['args'];
         $methodName = $value['name'];
         $methodComment = $value['comment'];
         $description = MethodTable::getMethodDescription($methodComment) . " " . MethodTable::getMethodCommentAttribute($methodComment, "desc");
         $description = trim($description);
         $access = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "access");
         $roles = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "roles");
         $instance = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "instance");
         $returns = MethodTable::getMethodCommentAttributeFirstLine($methodComment, "returns");
         $pagesize = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "pagesize");
         $params = MethodTable::getMethodCommentArguments($methodComment);
         //description, arguments, access, [roles, [instance, [returns, [pagesize]]]]
         $methodTable[$methodName] = array();
         //$methodTable[$methodName]["signature"] = $methodSignature; //debug purposes
         $methodTable[$methodName]["description"] = $description == "" ? "No description given." : $description;
         $methodTable[$methodName]["arguments"] = MethodTable::getMethodArguments($methodSignature, $params);
         $methodTable[$methodName]["access"] = $access == "" ? "private" : $access;
         if ($roles != "") {
             $methodTable[$methodName]["roles"] = $roles;
         }
         if ($instance != "") {
             $methodTable[$methodName]["instance"] = $instance;
         }
         if ($returns != "") {
             $methodTable[$methodName]["returns"] = $returns;
         }
         if ($pagesize != "") {
             $methodTable[$methodName]["pagesize"] = $pagesize;
         }
     }
     $classComment = trim(str_replace("\r\n", "\n", MethodTable::getMethodDescription($classComment)));
     return $methodTable;
 }
예제 #5
0
 /**
  * Prints out the headers and footers of the method testing page and
  * either prints a form (through _printForm) for the user to enter arguments or, if arguments
  * are provided, prints the result of the method (through printResult).
  */
 function testMethod($name)
 {
     if (isset($this->_classConstruct->methodTable[$name]['arguments'])) {
         return $this->_classConstruct->methodTable[$name]['arguments'];
     } else {
         require_once AMFPHP_BASE . 'util/MethodTable.php';
         $mt = MethodTable::create(substr($_GET['class'], strrpos('/' . $_GET['class'], '/')) . '.php');
         return $mt[$name]['arguments'];
     }
 }
예제 #6
0
 /**
  * Cleans the arguments array.
  * This method removes all whitespaces and the leading "$" sign from each argument
  * in the array.
  *
  * @static
  * @access private
  * @param $args(Array) The "dirty" array with arguments.
  */
 function cleanArguments($args, $commentParams)
 {
     $result = array();
     if (!is_array($args)) {
         return array();
     }
     foreach ($args as $index => $arg) {
         $arg = strrstr(str_replace(array('$', '&$'), array('', '&'), $arg), '=');
         if (!isset($commentParams[$index])) {
             $result[] = trim($arg);
         } else {
             $start = trim($arg);
             $end = trim(str_replace('$', '', $commentParams[$index]));
             // Suppress Notice of 'Undefined offset' with @
             @(list($word0, $word1, $tail) = preg_split("/[\\s]+/", $end, 3));
             $word0 = strtolower($word0);
             $word1 = strtolower($word1);
             $wordBase0 = ereg_replace('^[&$]+', '', $word0);
             $wordBase1 = ereg_replace('^[&$]+', '', $word1);
             $startBase = strtolower(ereg_replace('^[&$]+', '', $start));
             if ($wordBase0 == $startBase) {
                 $type = str_replace(array('(', ')'), '', $word1);
             } elseif ($wordBase1 == $startBase) {
                 $type = str_replace(array('(', ')'), '', $word0);
             } elseif (ereg('(^[&$]+)|(\\()([a-z0-9]+)(\\)$)', $word0, $regs)) {
                 $tail = str_ireplace($word0, '', $end);
                 $type = $regs[3];
             } else {
                 // default to string
                 $type = 'string';
             }
             $type = MethodTable::standardizeType($type);
             /*
                             if($type == 'str') {
                                 $type = 'string';
                             } elseif($type == 'int' || $type == 'integer') {
                                 $type = 'int';
                             } elseif($type == 'bool' || $type == 'boolean') {
                                 $type = 'boolean';
                             } elseif($type == 'object' || $type == 'class') {
                                 // Note that this is not a valid XMLRPC type
                                 $type = 'object';
                             } elseif($type == 'float' || $type == 'dbl' || $type == 'double' || $type == 'flt') {
                                 $type = 'double';
                             } elseif($type == 'null') {
                                 // Note that this is not a valid XMLRPC type
                                 // The null type can have only one value - null. Why would 
                                 // that be an argument to a function? Just in case:
                                 $type = 'null';
                             } elseif($type == 'mixed') {
                                 // Note that this is not a valid XMLRPC type
                                 $type = 'mixed';
                             } elseif($type == 'array' || $type == 'arr') {
                                 $type = 'array';
                             } elseif($type == 'assoc') {
                                 $type = 'struct';
                             } elseif($type == 'reference' || $type == 'ref') {
                                 // Note that this is not a valid XMLRPC type
                                 // As references cannot be serialized or exported, there is
                                 // no way this could be XML-RPCed.
                                 $type = 'reference';
                             } else {
                                 $type = 'string';
                             }
             */
             $result[] = array('type' => $type, 'description' => $start . ' - ' . $tail);
         }
     }
     return $result;
 }
예제 #7
0
 /**
  * Returns an array with the arguments of a method.
  *
  * @static
  * @access private
  * @param $methodSignature (String)The method's signatureg;
  */
 function getMethodArguments($methodSignature, $commentParams)
 {
     if (strlen($methodSignature) < 2) {
         //no arguments, return an empty array
         $result = array();
     } else {
         //clean the arguments before returning them
         $result = MethodTable::cleanArguments(explode(",", $methodSignature), $commentParams);
     }
     return $result;
 }
예제 #8
0
	/**
	 * 
	 * 
	 */
	private static function getMethodCommentAttributeFirstWord($comment, $attribute){
		$pieces = strstrafter($comment, '@' . $attribute);
		if($pieces !== FALSE)
		{
			$val = MethodTable::cleanComment($pieces);
			return trim(strrstr($val, ' '));
		}
		return "";
	}
예제 #9
0
 /**
  * Creates the methodTable for a passed class.
  *
  * @static
  * @access public
  * @param $className(String) The name of the service class.
  *        May also simply be __FILE__
  * @param $servicePath(String) The location of the classes (optional)
  */
 function create($className, $servicePath = NULL, &$classComment)
 {
     $methodTable = array();
     if (file_exists($className)) {
         //The new __FILE__ way of doing things was used
         $sourcePath = $className;
         $className = str_replace("\\", '/', $className);
         $className = substr($className, strrpos($className, '/') + 1);
         $className = str_replace('.php', '', $className);
     } else {
         $className = str_replace('.php', '', $className);
         $fullPath = str_replace('.', '/', $className);
         $className = $fullPath;
         if (strpos($fullPath, '/') !== FALSE) {
             $className = substr(strrchr($fullPath, '/'), 1);
         }
         if ($servicePath == NULL) {
             if (isset($GLOBALS['amfphp']['classPath'])) {
                 $servicePath = $GLOBALS['amfphp']['classPath'];
             } else {
                 $servicePath = "../services/";
             }
         }
         $sourcePath = $servicePath . $fullPath . ".php";
     }
     if (!file_exists($sourcePath)) {
         trigger_error("The MethodTable class could not find {" . $sourcePath . "}", E_USER_ERROR);
     }
     //convert classname to cake classname
     $className = Inflector::camelize($className);
     if (class_exists('ReflectionClass')) {
         //PHP5
         $classMethods = MethodTable::getClassMethodsReflection($sourcePath, $className, $classComment);
     } else {
         //PHP4
         $classMethods = MethodTable::getClassMethodsTokenizer($sourcePath, $className, $classComment);
     }
     foreach ($classMethods as $key => $value) {
         if ($value['name'][0] == '_' || in_array($value['name'], array('beforeFilter', 'afterFilter', 'beforeRender', 'afterRender', 'Object', 'cakeError', 'cleanUpFields', 'constructClasses', 'flash', 'flashOut', 'generateFieldNames', 'log', 'postConditions', 'redirect', 'referer', 'render', 'requestAction', 'set', 'setAction', 'toString', 'validate', 'validateErrors', 'view'))) {
             continue;
         }
         $methodSignature = $value['args'];
         $methodName = $value['name'];
         $methodComment = $value['comment'];
         $description = MethodTable::getMethodDescription($methodComment) . " " . MethodTable::getMethodCommentAttribute($methodComment, "desc");
         $description = trim($description);
         $access = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "access");
         $roles = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "roles");
         $instance = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "instance");
         $returns = MethodTable::getMethodCommentAttributeFirstLine($methodComment, "returns");
         $pagesize = MethodTable::getMethodCommentAttributeFirstWord($methodComment, "pagesize");
         $params = MethodTable::getMethodCommentArguments($methodComment);
         //description, arguments, access, [roles, [instance, [returns, [pagesize]]]]
         $methodTable[$methodName] = array();
         //$methodTable[$methodName]["signature"] = $methodSignature; //debug purposes
         $methodTable[$methodName]["description"] = $description == "" ? "No description given." : $description;
         $methodTable[$methodName]["arguments"] = MethodTable::getMethodArguments($methodSignature, $params);
         $methodTable[$methodName]["access"] = $access == "" ? "private" : $access;
         if ($roles != "") {
             $methodTable[$methodName]["roles"] = $roles;
         }
         if ($instance != "") {
             $methodTable[$methodName]["instance"] = $instance;
         }
         if ($returns != "") {
             $methodTable[$methodName]["returns"] = $returns;
         }
         if ($pagesize != "") {
             $methodTable[$methodName]["pagesize"] = $pagesize;
         }
     }
     $classComment = trim(str_replace("\r\n", "\n", MethodTable::getMethodDescription($classComment)));
     return $methodTable;
 }
예제 #10
0
	<head>
		<title>MethodTable</title>
		<link rel="stylesheet" type="text/css" href="images/service-browser.css" />
	</head>
	<body>
		<h1>MethodTable for <?php 
echo $_GET['class'] . '.php';
?>
</h1>
		<?php 
echo $feedback;
?>
        
		<p>This code was generated by the MethodTable class by looping through the class methods and reading the signature and JavaDoc of each method. Read more about it in the <a href="http://www.amfphp.org/docs/creatingclasses.html" target="_blank">amfphp docs</a>.<br/><br/>When deploying your application on a webserver it's better to have a hard-coded methodTable for faster performance. You can copy/paste this code in the constructor of your service class, or, provided you have 777 permissions in /services, click the 'save' link,  and write <code>include("<?php 
echo substr($className, strrpos('/' . $className, '/'));
?>
.methodTable.php");</code> in the constructor.</p>

		<div style='text-align:right'><a href='<?php 
echo $PHP_SELF . '?class=' . $_GET['class'] . '&action=save';
?>
'>Save to <?php 
echo $className;
?>
.methodTable.php</a></div>
		<textarea class="codex" name="methodTable"><?php 
echo MethodTable::showCode($methodTable);
?>
</textarea>
	</body>
</html>