Esempio n. 1
0
 /**
  * 	method: getCallback
  *
  * 	Use the callback data to generate a callback usable in call_user_func* function.  This
  * 	function can be provided with a fallback plugin or api object in case the detected plugin
  * 	doesn't exist.  This is especially useful when the plugins are being loaded, it's not fully
  * 	installed in the system, but it's required to generate a callback
  *
  * 	params:
  * 		$callback - An array of data for the callback, or a string of comma separated parts
  * 		$fallback - Either null, a Plugin or API object
  *
  * 	returns:
  * 		-	A callback in any case, if there is a problem with the data, it passed an exception
  * 			callback which will fail on execution
  *
  * 	variatons:
  * 		-	array(plugin,object,method)
  * 		-	array(plugin,method)
  * 		-	"plugin,object,method => explode(,) => array(plugin,object,method) <-- array
  * 		-	"plugin,method" => explode(,) => array(plugin,method) <-- array
  * 		-	array(Object,method) <-- not static / array
  * 		-	array(Class,method) <-- static / string
  * 		-	"Class::method" <-- string
  * 		-	"straightFunction" <-- string
  */
 public static function getCallback($callback, $fallback = null)
 {
     $method = __METHOD__;
     //	set output/invalid to be this default callback which throws an exception
     //	this is so we can catch bad callbacks and trace them back to where they
     //	where constructed
     $output = $invalid = function () use($method, $callback) {
         $args = func_get_args();
         throw new Amslib_Exception("{$method}, callback was not valid", array("callback" => $callback instanceof Closure ? "was closure" : $callback, "arguments" => $args));
     };
     //	supports: "plugin,object,method => array(plugin,object,method)
     //	supports: "plugin,method" => array(plugin,method)
     if (is_string($callback) && strpos($callback, ",") !== false) {
         $callback = explode(",", $callback);
     }
     //	supports: array(Object,method)
     //	supports: array(plugin,object,method)
     //	supports: array(plugin,method)
     if (is_array($callback) && in_array(count($callback), [2, 3])) {
         //	The first element has to be an object or a plugin
         $plugin = array_shift($callback);
         //	The last element in the array is always the method, if there is a third element
         //	it will sit inside the middle, [plugin, >>>HERE<<<, method] and will be the object
         //	But the third parameter is not necessary, if it's missing, the plugins API object is used
         $method = array_pop($callback);
         if (is_string($plugin) && !empty($plugin)) {
             //	supports: array(plugin,object,method)
             //	supports: array(plugin,method)
             $plugin = Amslib_Plugin_Manager::getAPI($plugin);
         } else {
             if (is_object($plugin)) {
                 //	supports: array(Object,method)
                 $output = array($plugin, $method);
             }
         }
         if (!$plugin) {
             //	supports: array(Class,method)
             if (class_exists($plugin)) {
                 //	The plugin was not found, therefore this must be a array(Class,Method) type call
                 $output = array($plugin, $method);
             } else {
                 if ($fallback instanceof Amslib_Plugin) {
                     //	If plugin is invalid and you were passed a plugin object
                     $plugin = $fallback->getAPI();
                 } else {
                     if ($fallback instanceof Amslib_MVC) {
                         //	If plugin is invalid and the method was passed an API object
                         $plugin = $fallback;
                     }
                 }
             }
         }
         if ($plugin) {
             //	Get the object to use in the callback
             $object = !empty($callback) ? array_shift($callback) : false;
             $object = !empty($object) && is_string($object) ? $plugin->getObject($object) : $plugin;
             //	From the information, generate a new callback
             $output = array($object, $method);
         }
     } else {
         //	supports: "Class::method"
         //	supports: "theFunctionCall"
         //	note: we don't need to do anything to support this, just fall into the else statement
     }
     //	Return the callback, or a not_found default callback which throws an exception when called
     return is_callable($output) ? $output : $invalid;
 }
Esempio n. 2
0
 /**
  * 	method:	getAPI
  *
  * 	todo: write documentation
  */
 public function getAPI($name = NULL)
 {
     return $name ? Amslib_Plugin_Manager::getAPI($name) : $this;
 }
 public function initialise()
 {
     //	Quickly insert this plugin object before we load anything else
     //	We do this so other plugins that might call the application can access this plugins
     //	configuration before the entire tree is loaded, because in a tree algorithm, all the
     //	other plugins are loaded into the system before this one, which causes a problem because
     //	of course if you need to talk to or through the application object, if you have not fully
     //	explored the tree, it won't exist, this obviously causes a lot of problems, so we need to
     //	"insert" a incomplete plugin here, so at least the plugin configurtion is available even
     //	if the actual API is not, when configuring the plugin tree, we 100% of the time always deal
     //	with the plugin object, not the API which is created after the plugin is fully loaded
     Amslib_Plugin_Manager::insert($this->getName(), $this);
     //	Set the base locations to load plugins from
     //	NOTE: this obviously means it's not configurable, since I'm hardcoding the path for this here
     Amslib_Plugin_Manager::addLocation($this->getLocation());
     Amslib_Plugin_Manager::addLocation($this->getLocation() . "/plugins");
     //	We can't use Amslib_Plugin_Manager for this, because it's an application plugin
     $this->config($this->getName());
     //	Process all the imports and exports so all the plugins contain the correct data
     Amslib_Plugin_Manager::processImport();
     Amslib_Plugin_Manager::processExport();
     //	Now we have to load all the plugins into the system
     $this->load();
     //	NOTE:	perhaps we can add a default callback for running the method Amslib_Plugin_Manager::processTransfers
     //	NOTE:	after all the plugins are loaded, do we need ot keep the plugin objects in memory, perhaps we should
     //			dump them all once all the API objects are created
     //	NOTE:	perhaps we register a completion callback to manually take care of this, it sounds like a useful way
     //			to save some memory, all those xml objects must take up space and especially the bulky confguration arrays
     //	NOTE:	we currently are deleting it inside the plugin code, perhaps this is not elegant
     $this->runCompletionCallbacks();
 }
Esempio n. 4
0
 public static function processExport()
 {
     foreach (self::$export as $key => $list) {
         foreach ($list as $name => $value) {
             $src = is_string($value["src"]) ? self::getPlugin($value["src"]) : $value["src"];
             $dst = is_string($value["dst"]) ? self::getPlugin($value["dst"]) : $value["dst"];
             $data = false;
             if (!$src || !$dst) {
                 $sname = is_object($src) ? $src->getName() : "searched: {$value["src"]}";
                 $dname = is_object($dst) ? $dst->getName() : "searched: {$value["dst"]}";
                 Amslib_Debug::log("plugin list", Amslib_Plugin_Manager::listPlugin());
                 Amslib_Debug::log("plugin invalid", intval(is_object($src)) . ", " . intval(is_object($dst)), $sname, $dname, Amslib_Router::getPath());
                 continue;
             }
             switch ($value["key"]) {
                 case "stylesheet":
                 case "javascript":
                 case "font":
                     die("[DIE]EXPORT[{$key}] => " . Amslib_Debug::pdump(true, array($src->getName(), $dst->getName(), $value["key"], $value["val"])));
                     break;
                 case "view":
                 case "value":
                     //	NOTE:	if I could change getValue to this, I could refactor all of these branches
                     //			together maybe into something very generic
                     //	NOTE:	the new import/export system works slightly differently from the old one,
                     //			we push directly into the import/export queues the information that we
                     //			want to pass and it doesn't enter the host plugin, this way, we can skip
                     //			a lot of bullshit with regard to internal data and data which is destined
                     //			for other plugins, the getValue method should in this case, circumstantially
                     //			create objects or just parse the data out of the structure, but it's not
                     //			about "getting" the value from the pluing, the $value variable already has
                     //			it and in many cases we don't need to do anything except return a particular
                     //			key depending on the stucture or type of that data, but in the case of
                     //			translators, objects or models, we need to ask the host plugin to create
                     //			the object on our behalf and then return and use it, because it might be
                     //			that the host plugin is the only plugin which has the correct functionality
                     //			necessary to create that object, in these cases getValue will do more than
                     //			just return a particular key, but will actually process the input data into
                     //			an "output data" to use
                     //$data = $src->getValue($value);
                     $dst->setValue($value["key"], $value["val"]);
                     break;
                 case "service":
                     //Amslib_FirePHP::output("export",$item);
                     //	Hmmm, I need a test case cause otherwise I won't know if this works
                     break;
                 case "image":
                     $dst->setValue($value["key"], $value["val"]);
                     break;
                     //	We do nothing special with these entries, we simply pass them
                 //	We do nothing special with these entries, we simply pass them
                 case "model":
                 case "translator":
                 default:
                     //	NOTE: I should change $value["key"] here to $value and make "key" something getValue uses internally
                     $data = $src->getValue($value["key"]);
                     $dst->setValue($value["key"], $data);
                     break;
             }
         }
     }
     self::$export = NULL;
 }