Initial import of code from 2005
This code was an evolution of an example I published on weberdev.com as a "Java like package loader". Was written in 2005.
This commit is contained in:
commit
9f52f2c0b7
8
Authors
Normal file
8
Authors
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#
|
||||||
|
# PHPNuts authors file
|
||||||
|
#
|
||||||
|
|
||||||
|
Full Name: Víctor Román Archidona
|
||||||
|
Position.: Main developer
|
||||||
|
E-Mail...: contacto@victor-roman.es
|
||||||
|
Web Site.: http://www.victor-roman.es/
|
165
License
Normal file
165
License
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
478
phpnuts.class.php
Normal file
478
phpnuts.class.php
Normal file
|
@ -0,0 +1,478 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* PHP-Nuts. A PHP package loader system.
|
||||||
|
* Copyright (C) 2005 Víctor Román Archidona <contacto@victor-roman.es>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
class PHPNuts {
|
||||||
|
private static $classpath = array (); /**< Our classpath */
|
||||||
|
private static $packages = array (); /**< Loaded packages */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn getLoadedPackages()
|
||||||
|
* \brief Returns the currently loaded packages
|
||||||
|
*
|
||||||
|
* This functions returns (in an array) the current list of loaded
|
||||||
|
* packages.
|
||||||
|
*/
|
||||||
|
public static function getLoadedPackages() {
|
||||||
|
return self::$packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn setClassPath($path)
|
||||||
|
* \brief Adds a path to PHP-Nuts search classpath.
|
||||||
|
*
|
||||||
|
* \param $path Path to be added
|
||||||
|
*
|
||||||
|
* We must set where PHP-Nuts must search for any package. This function
|
||||||
|
* adds the specified path to do this mission.
|
||||||
|
*/
|
||||||
|
public static function setClassPath($path) {
|
||||||
|
$current_path = self::getClassPath();
|
||||||
|
$new_path = (array) $path;
|
||||||
|
|
||||||
|
self::$classpath = array_merge($current_path, $new_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn getClassPath($as_array = true)
|
||||||
|
* \brief Retuns the current classpath
|
||||||
|
* \param $package Package to be loaded
|
||||||
|
* \param $as Optionally variable which will contain the new instance (by reference).
|
||||||
|
* \return An array with every path if first param is true
|
||||||
|
* \return A line broken by ';' if the first param is false
|
||||||
|
*
|
||||||
|
* This functions allows the programmer to get the current classpath
|
||||||
|
* used by the class where it search the packages.
|
||||||
|
*/
|
||||||
|
public static function getClassPath($as_array = true) {
|
||||||
|
/*
|
||||||
|
* Is possible to return our classpath in two different
|
||||||
|
* flavors:
|
||||||
|
*
|
||||||
|
* By default: Returns an array
|
||||||
|
* In a line.: In the same line returns the classpath, broken
|
||||||
|
* by ';'.
|
||||||
|
*/
|
||||||
|
if ($as_array == true) {
|
||||||
|
return (array) self::$classpath;
|
||||||
|
} else {
|
||||||
|
$retval = implode(";", self::$classpath);
|
||||||
|
return $retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn PackageLoad($package, &$as = NULL)
|
||||||
|
* \brief Loads a package searching for it in the classpath
|
||||||
|
*
|
||||||
|
* \param $package Package to be loaded
|
||||||
|
* \param $as Optionally variable which will contain the new instance (by reference).
|
||||||
|
*
|
||||||
|
* \return An instancie to a new object in the second parameter is specified
|
||||||
|
* \return An instancie to a new object
|
||||||
|
*
|
||||||
|
* This function loads the package and returns an instance to it if the
|
||||||
|
* function was called with one parameter, or stores it into the second
|
||||||
|
* parameter.
|
||||||
|
*
|
||||||
|
* If is a superpackage (tld_domain.* or tld_domain.package.*), the function
|
||||||
|
* returns an array with the instances as show:
|
||||||
|
* $array['tld.domain'] = Main package instance
|
||||||
|
* $array['tld.domain.package'] AND $array['package'] = Subpackage instance
|
||||||
|
*/
|
||||||
|
public static function Load($package, & $as = null) {
|
||||||
|
if (self::isPackageLoaded($package)) {
|
||||||
|
trigger_error("Package $package was previously loaded.", E_USER_WARNING);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($package[strlen($package) - 1] != '*')
|
||||||
|
return self::packageLoad($package, $as);
|
||||||
|
else
|
||||||
|
return self::packageLoadRecursive($package, $as);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn isPackageLoaded($package)
|
||||||
|
* \brief Checks if a package was previously loaded
|
||||||
|
*
|
||||||
|
* \param $package Package to be checked
|
||||||
|
*
|
||||||
|
* \return 0 If the package is not loaded
|
||||||
|
* \return 1 If the package was loaded before
|
||||||
|
*
|
||||||
|
* With isPackageLoaded we can check if the specified package was
|
||||||
|
* loaded before with a 'Load' method call.
|
||||||
|
*/
|
||||||
|
public static function isPackageLoaded($package) {
|
||||||
|
$package = strtolower($package);
|
||||||
|
return in_array($package, self::$packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn packageAdd($package)
|
||||||
|
* \brief Adds a package to internal package array list
|
||||||
|
*
|
||||||
|
* \param $package Package to be added to our internal array list
|
||||||
|
*
|
||||||
|
* After load a package, it MUST be added to the internal packages
|
||||||
|
* list to skip problems loading the same package two or more times.
|
||||||
|
*/
|
||||||
|
private static function packageAdd($package) {
|
||||||
|
if (!in_array($package, self::$packages))
|
||||||
|
self::$packages[] = strtolower($package);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn PackageLoad($package, &$as = NULL)
|
||||||
|
* \brief Loads a package searching for it in the classpath
|
||||||
|
* \param $package Package to be loaded
|
||||||
|
* \param $as Optionally variable which will contain the new instance (by reference).
|
||||||
|
* \return An instancie to a new object in the second parameter is specified
|
||||||
|
* \return An instancie to a new object
|
||||||
|
*
|
||||||
|
* This function loads the package using one of the two available kinds
|
||||||
|
* to do it:
|
||||||
|
* - The first is putting the class into tld/domain with the class name
|
||||||
|
* and adding .class.php (IE: tld/domain/ClassName/ClassName.class.php). The class
|
||||||
|
* will be caled "ClassName":
|
||||||
|
* class ClassName
|
||||||
|
* {
|
||||||
|
* [code]
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* - The second is very similar. Puts the class into tld/domain and call
|
||||||
|
* it "ClassName.class.php" (tld/domain/ClassName/ClassName.class.php). BUT in
|
||||||
|
* his definition, it MUST me called tld_domain_classname. With this kind
|
||||||
|
* of call, avoid redefining classes is much more easiest.
|
||||||
|
* class tld_domain_ClassName
|
||||||
|
* {
|
||||||
|
* [code]
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Is transparent which kind had you used, this functions try to determine
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
private static function packageLoad($package, & $as = null) {
|
||||||
|
/* The following variable is false until the class file is found */
|
||||||
|
$found = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extracts the file name. With this filename also builds the
|
||||||
|
* $classfile adding ".class.php";
|
||||||
|
*/
|
||||||
|
$file = substr($package, strrpos($package, '.') + 1);
|
||||||
|
$classfile = $file.".class.php";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now the directory to search. It is build in as shown below:
|
||||||
|
*
|
||||||
|
* With the package name: tld.domain.Package, first gets off
|
||||||
|
* the "Package". This Package is the final filename with
|
||||||
|
* .class.php added ("Package.class.php").
|
||||||
|
*
|
||||||
|
* The directory "tld/domain" is build replacing the '.' (dots)
|
||||||
|
* with a '/' (slash) using str_replace.
|
||||||
|
*/
|
||||||
|
$directory = substr($package, 0, -strlen($file) - 1);
|
||||||
|
$directory = str_replace('.', '/', $directory);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we iterate over $classpath to search where the
|
||||||
|
* directory will be. When the directory is found, try
|
||||||
|
* to search for the class file, and sets $found to true
|
||||||
|
* if the file is found.
|
||||||
|
*/
|
||||||
|
foreach (self::getClassPath() as $cpath) {
|
||||||
|
$cpath = $cpath.'/'.$directory.'/'.$file;
|
||||||
|
|
||||||
|
if (is_dir($cpath)) {
|
||||||
|
$classfile = $cpath.'/'.$classfile;
|
||||||
|
|
||||||
|
if (is_file($classfile)) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the file was not found, advertise the user to correct
|
||||||
|
* his classpath.
|
||||||
|
*/
|
||||||
|
if ($found !== true) {
|
||||||
|
trigger_error("Package $package not found on CLASSPATH", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Includes the file (only once) */
|
||||||
|
include_once "$classfile";
|
||||||
|
|
||||||
|
$classname = $file;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the class exists (based on the previous step). If it
|
||||||
|
* not exists, warns the user.
|
||||||
|
*/
|
||||||
|
if (!class_exists($classname)) {
|
||||||
|
$new_classname = str_replace('/', '_', $directory).'_'.$file;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If "class ClassName" does not exists search for the other
|
||||||
|
* possible construction "class tld_domain_classname".
|
||||||
|
*/
|
||||||
|
if (!class_exists($new_classname)) {
|
||||||
|
trigger_error("Neither \"$classname\" nor \"$new_classname\" class exists on package $package", E_USER_ERROR);
|
||||||
|
} else {
|
||||||
|
/* Sets the fixed name into $classname */
|
||||||
|
$classname = $new_classname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds the loaded package to internal array packages list */
|
||||||
|
self::packageAdd($package);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code determines how many args was the function called with. Is
|
||||||
|
* necessary to determine what kind of operation do it, and will be of
|
||||||
|
* two types:
|
||||||
|
*
|
||||||
|
* Only one argument: Object is returned with return an assigned to
|
||||||
|
* calling variable.
|
||||||
|
* Two arguments: The variable in the second parameter is used to put
|
||||||
|
* (by reference) an instance to the class loaded.
|
||||||
|
*/
|
||||||
|
$numargs = func_num_args();
|
||||||
|
|
||||||
|
if ($numargs == 1)
|
||||||
|
return new $classname;
|
||||||
|
else
|
||||||
|
(object) $as = new $classname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn PackageLoad($package, &$as = NULL)
|
||||||
|
* \brief Loads a package searching for it in the classpath
|
||||||
|
*
|
||||||
|
* \param $package Package to be loaded
|
||||||
|
* \param $as Optionally variable which will contain the new instance (by reference).
|
||||||
|
*
|
||||||
|
* \return An instancie to a new object in the second parameter is specified
|
||||||
|
* \return An instancie to a new object
|
||||||
|
*
|
||||||
|
* This function loads entire package and his subpackages into an array if
|
||||||
|
* it was specified as second parameter, or returns them if only wass called
|
||||||
|
* with one parameter.
|
||||||
|
*
|
||||||
|
* The kind of resultant array is:
|
||||||
|
*
|
||||||
|
* $array['tld.domain.package'] AND $array['package'] = Subpackage instance
|
||||||
|
*/
|
||||||
|
private static function packageLoadRecursive($package, & $as) {
|
||||||
|
/* Drops ".*" from the package name */
|
||||||
|
$pkg = substr($package, 0, -2);
|
||||||
|
|
||||||
|
/* Builds the "virtual" package path */
|
||||||
|
$pkg_path = str_replace('.', '/', $pkg);
|
||||||
|
|
||||||
|
foreach (self::$getClassPath() as $cpath) {
|
||||||
|
/* Real path is "SEARCH_PATH/PACKAGE_PATH" */
|
||||||
|
$real_path = $cpath.'/'.$pkg_path;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the search path not exists, continues the iteration with
|
||||||
|
* the following classpath entry.
|
||||||
|
*
|
||||||
|
* FIXME: If $real_path does not exists, we MUST NOT continue
|
||||||
|
* without try to search the alternative path. This alternative
|
||||||
|
* path is build taking the current path, and search for the
|
||||||
|
* package here.
|
||||||
|
*/
|
||||||
|
if (!is_dir($real_path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Si el directorio existe, obtiene el listado de ficheros */
|
||||||
|
$files = self::searchFilesToInclude($real_path);
|
||||||
|
|
||||||
|
/* Try to load every packet one by one */
|
||||||
|
foreach ($files as $file) {
|
||||||
|
/* Drops the current search path */
|
||||||
|
$to_load = substr($file, strlen($cpath) + 1);
|
||||||
|
|
||||||
|
/* Drops ClassName.class.php */
|
||||||
|
$to_load = substr($to_load, 0, strrpos($to_load, '/'));
|
||||||
|
|
||||||
|
/* Replaces directories '/' with packages '.' */
|
||||||
|
$to_load = str_replace('/', '.', $to_load);
|
||||||
|
|
||||||
|
/* Convert to lower case */
|
||||||
|
$to_load = strtolower($to_load);
|
||||||
|
|
||||||
|
/* Now loads it */
|
||||||
|
$pkg_name = substr($to_load, strlen($pkg) + 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* And finally builds the array. In first place we check
|
||||||
|
* if $pkg_name after drops exists. If it exists is a
|
||||||
|
* subpackage, and assings it to the array as show:
|
||||||
|
*
|
||||||
|
* $array['tld.domain.subpackage']; AND
|
||||||
|
* $array['subpackage']
|
||||||
|
*
|
||||||
|
* If $pkg_name does not exists is the base package, and
|
||||||
|
* assigns to the array as shows:
|
||||||
|
*
|
||||||
|
* $array['tld.domain']
|
||||||
|
*/
|
||||||
|
if ($pkg_name) {
|
||||||
|
self::packageLoad($to_load, $as[$pkg_name]);
|
||||||
|
$as[$pkg.'.'.$pkg_name] = $as[$pkg_name];
|
||||||
|
} else {
|
||||||
|
self::packageLoad($to_load, $as[$pkg]);
|
||||||
|
}
|
||||||
|
} /* Foreach files */
|
||||||
|
} /* Foreach classpath */
|
||||||
|
|
||||||
|
if ($as && (func_num_args() == 1))
|
||||||
|
return $as;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn getAvailablePackages()
|
||||||
|
* \brief Gets the available packages searching them in the classpath.
|
||||||
|
*
|
||||||
|
* \return An array with the available packages
|
||||||
|
* \return NULL if there is not any package.
|
||||||
|
*
|
||||||
|
* With getAvailablePackages we can get an array list with all available
|
||||||
|
* packages. This function searchs for them in the classpath, and returns
|
||||||
|
* the result or NULL if none is found.
|
||||||
|
*/
|
||||||
|
public static function getAvailablePackages() {
|
||||||
|
$retval = array ();
|
||||||
|
|
||||||
|
foreach (self::getClassPath() as $cpath) {
|
||||||
|
$cpath_len = strlen($cpath);
|
||||||
|
|
||||||
|
foreach (self::searchFilesToInclude($cpath) as $file) {
|
||||||
|
$file = substr($file, $cpath_len +1);
|
||||||
|
$file = substr($file, 0, strrpos($file, '/'));
|
||||||
|
$file = str_replace('/', '.', $file);
|
||||||
|
|
||||||
|
$retval[] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count($retval) ? $retval : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn Unload($package, &$as = NULL)
|
||||||
|
* \brief Unloads a package cleaning his content
|
||||||
|
* \param $as Object where the package was loaded
|
||||||
|
*
|
||||||
|
* Destroys the variable fixing her value to NULL and doing an unset
|
||||||
|
* after it.
|
||||||
|
*/
|
||||||
|
public static function Unload(& $as) {
|
||||||
|
$as = null;
|
||||||
|
unset ($as);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \fn searchFilesToInclude($parent, $autocall = false)
|
||||||
|
* \brief Searchs files recursively to be loaded after.
|
||||||
|
*
|
||||||
|
* \param $parent Main directory to search ("root directory")
|
||||||
|
* \param $autocall Set it to true if you call this function from inside it.
|
||||||
|
*
|
||||||
|
* \return An array with the files
|
||||||
|
* \return NULL if he can found any file
|
||||||
|
*
|
||||||
|
* This functions searchs on the specified parent and in all his subdirs
|
||||||
|
* for "Package/Package.class.php". The param $autocall is a hack to
|
||||||
|
* destroy the $ar_files array inside it, because if the function is
|
||||||
|
* called two times it returns the result of the first execution PLUS
|
||||||
|
* results of second execution.
|
||||||
|
*
|
||||||
|
* In the very near future this function should be rewritten or entirely
|
||||||
|
* drop, due is a problem origin.
|
||||||
|
*/
|
||||||
|
private static function searchFilesToInclude($parent, $autocall = false) {
|
||||||
|
/* Internal file array */
|
||||||
|
static $ar_files = array ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the function is not called from it, we drop the previous
|
||||||
|
* content stored in $ar_files. Read the function documentation
|
||||||
|
* to know more about this.
|
||||||
|
*/
|
||||||
|
if (!$autocall)
|
||||||
|
$ar_files = array ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the specified directory is not a directory (yups), we
|
||||||
|
* return NULL. With this isn't necessary check if the directory
|
||||||
|
* handler is valid after. Also drops a possible error if the
|
||||||
|
* directory not exists (without hide the warning with @).
|
||||||
|
*/
|
||||||
|
if (!is_dir($parent))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Opens the directory to be readed */
|
||||||
|
$dh = opendir($parent);
|
||||||
|
|
||||||
|
/* Extracts the base directory which class resides */
|
||||||
|
$class_directory = substr($parent, strrpos($parent, '/') + 1);
|
||||||
|
|
||||||
|
/* Full path to class file */
|
||||||
|
$file = $parent.'/'.$class_directory.".class.php";
|
||||||
|
|
||||||
|
/* Reads the current directory (with his subdirectories) */
|
||||||
|
while (($current = readdir($dh)) !== false) {
|
||||||
|
/*
|
||||||
|
* Skips the current (.) and previous (..) directory to
|
||||||
|
* avoid an infinite loop.
|
||||||
|
*/
|
||||||
|
if ($current == '.' || $current == "..")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the file exists and was not previously stored into our
|
||||||
|
* internal files array, we store it.
|
||||||
|
*/
|
||||||
|
if (is_file($file) && !in_array($file, $ar_files)) {
|
||||||
|
$ar_files[] = $file;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Makes the recursive search. If the current data in $current is
|
||||||
|
* a directory, we read it calling this funcion, and passing 'true'
|
||||||
|
* as second parameter DUE THIS IS AN INTERNAL AUTOCALL.
|
||||||
|
*/
|
||||||
|
if (is_dir($parent.'/'.$current))
|
||||||
|
self::searchFilesToInclude($parent.'/'.$current, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the directory handler */
|
||||||
|
closedir($dh);
|
||||||
|
|
||||||
|
/* Returns an array with the full path to the files, or NULL */
|
||||||
|
return count($ar_files) ? $ar_files : NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
Loading…
Reference in a new issue