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