/** * Removes files matching given pattern. * * @param string $pattern */ protected function removeFiles($pattern) { $directory = FileUtil::unifyDirSeperator(WCF_DIR.'cache/'); $pattern = str_replace('*', '.*', str_replace('.', '\.', $pattern)); DirectoryUtil::getInstance($directory)->executeCallback(new Callback(function ($filename) { if (!@touch($filename, 1)) { @unlink($filename); } }), new Regex('^'.$directory.$pattern.'$', Regex::CASE_INSENSITIVE)); }
/** * Uninstalls the files of this package. */ public function uninstall() { // get absolute package dir $packageDir = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator(realpath(WCF_DIR . $this->installation->getPackage()->packageDir))); // create file list $files = array(); // get files from log $sql = "SELECT\t*\n\t\t\tFROM\twcf" . WCF_N . "_package_installation_file_log\n\t\t\tWHERE \tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->installation->getPackageID())); while ($row = $statement->fetchArray()) { $files[] = $row['filename']; } if (count($files) > 0) { // delete files $this->installation->deleteFiles($packageDir, $files); // delete log entries parent::uninstall(); } }
/** * Prompts for a text input for package directory (applies for applications only) * * @return wcf\system\form\FormDocument */ protected function promptPackageDir() { if (!PackageInstallationFormManager::findForm($this->queue, 'packageDir')) { $container = new GroupFormElementContainer(); $packageDir = new TextInputFormElement($container); $packageDir->setName('packageDir'); $packageDir->setLabel(WCF::getLanguage()->get('wcf.acp.package.packageDir.input')); $path = RouteHandler::getPath(array('wcf', 'acp')); $defaultPath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator($_SERVER['DOCUMENT_ROOT'] . $path)); $packageDir->setValue($defaultPath); $container->appendChild($packageDir); $document = new FormDocument('packageDir'); $document->appendContainer($container); PackageInstallationFormManager::registerForm($this->queue, $document); return $document; } else { $document = PackageInstallationFormManager::getForm($this->queue, 'packageDir'); $document->handleRequest(); $packageDir = $document->getValue('packageDir'); if ($packageDir !== null) { // validate package dir if (file_exists(FileUtil::addTrailingSlash($packageDir) . 'global.php')) { $document->setError('packageDir', WCF::getLanguage()->get('wcf.acp.package.packageDir.notAvailable')); return $document; } // set package dir $packageEditor = new PackageEditor($this->getPackage()); $packageEditor->update(array( 'packageDir' => FileUtil::getRelativePath(WCF_DIR, $packageDir) )); // parse domain path $domainPath = FileUtil::getRelativePath(FileUtil::unifyDirSeperator($_SERVER['DOCUMENT_ROOT']), FileUtil::unifyDirSeperator($packageDir)); // work-around for applications installed in document root if ($domainPath == './') { $domainPath = ''; } $domainPath = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash($domainPath)); // update application path $application = new Application($this->getPackage()->packageID); $applicationEditor = new ApplicationEditor($application); $applicationEditor->update(array( 'domainPath' => $domainPath, 'cookiePath' => $domainPath )); // create directory and set permissions @mkdir($packageDir, 0777, true); @chmod($packageDir, 0777); } return null; } }
/** * Redirects the user agent. * * @param string $location * @param boolean $prependDir * @param boolean $sendStatusCode */ public static function redirect($location, $prependDir = true, $sendStatusCode = false) { if ($prependDir) { // remove path info from request URI $requestURI = WCF::getSession()->requestURI; if (($pos = strpos($requestURI, '.php')) !== false) { $requestURI = substr($requestURI, 0, $pos + 4); } $location = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator(dirname($requestURI))) . $location; } //if ($sendStatusCode) @header('HTTP/1.0 301 Moved Permanently'); if ($sendStatusCode) { @header('HTTP/1.1 307 Temporary Redirect'); } header('Location: ' . $location); }
/** * Returns the request uri of the active request. * * @return string */ public static function getRequestURI() { $REQUEST_URI = ''; $appendQueryString = true; if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], '.php') !== false) { $REQUEST_URI = $_SERVER['ORIG_PATH_INFO']; } else if (!empty($_SERVER['ORIG_SCRIPT_NAME'])) { $REQUEST_URI = $_SERVER['ORIG_SCRIPT_NAME']; } else if (!empty($_SERVER['SCRIPT_NAME']) && (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO']))) { $REQUEST_URI = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO']; } else if (isset($_SERVER['REQUEST_URI']) && !empty($_SERVER['REQUEST_URI'])) { $REQUEST_URI = $_SERVER['REQUEST_URI']; $appendQueryString = false; } else if (!empty($_SERVER['PHP_SELF'])) { $REQUEST_URI = $_SERVER['PHP_SELF']; } else if (!empty($_SERVER['PATH_INFO'])) { $REQUEST_URI = $_SERVER['PATH_INFO']; } if ($appendQueryString && !empty($_SERVER['QUERY_STRING'])) { $REQUEST_URI .= '?'.$_SERVER['QUERY_STRING']; } // fix encoding if (!StringUtil::isASCII($REQUEST_URI) && !StringUtil::isUTF8($REQUEST_URI)) { $REQUEST_URI = StringUtil::convertEncoding('ISO-8859-1', 'UTF-8', $REQUEST_URI); } return StringUtil::substring(FileUtil::unifyDirSeperator($REQUEST_URI), 0, 255); }
/** * Fills the list of available files, with DirectoryIterator object as value */ protected function scanFileObjects() { // value is cached if (!empty($this->fileObjects)) { return; } if ($this->recursive) { $it = new \RecursiveIteratorIterator($this->obj, \RecursiveIteratorIterator::CHILD_FIRST); foreach ($it as $filename => $obj) { // ignore . and .. if ($it->isDot()) { continue; } $this->fileObjects[FileUtil::unifyDirSeperator($filename)] = $obj; } } else { foreach ($this->obj as $obj) { // ignore . and .. if ($this->obj->isDot()) { continue; } $this->fileObjects[FileUtil::unifyDirSeperator($obj->getFilename())] = $obj; } } // add the directory itself $this->fileObjects[$this->directory] = new \SPLFileInfo($this->directory); }
/** * Exports this style. * * @param boolean $templates * @param boolean $images * @param string $packageName */ public function export($templates = false, $images = false, $packageName = '') { // create style tar $styleTarName = FileUtil::getTemporaryFilename('style_', '.tgz'); $styleTar = new TarWriter($styleTarName, true); // append style preview image if ($this->image && @file_exists(WCF_DIR.'images/'.$this->image)) { $styleTar->add(WCF_DIR.'images/'.$this->image, '', FileUtil::addTrailingSlash(dirname(WCF_DIR.'images/'.$this->image))); } // fetch style description $sql = "SELECT language.languageCode, language_item.languageItemValue FROM wcf".WCF_N."_language_item language_item LEFT JOIN wcf".WCF_N."_language language ON (language.languageID = language_item.languageID) WHERE language_item.languageItem = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->styleDescription)); $styleDescriptions = array(); while ($row = $statement->fetchArray()) { $styleDescriptions[$row['languageCode']] = $row['languageItemValue']; } // create style info file $xml = new XMLWriter(); $xml->beginDocument('style', 'http://www.woltlab.com', 'http://www.woltlab.com/XSD/maelstrom/style.xsd'); // general block $xml->startElement('general'); $xml->writeElement('stylename', $this->styleName); // style description foreach ($styleDescriptions as $languageCode => $value) { $xml->writeElement('description', $value, array('language' => $languageCode)); } $xml->writeElement('date', $this->styleDate); $xml->writeElement('version', $this->styleVersion); if ($this->image) $xml->writeElement('image', $this->image); if ($this->copyright) $xml->writeElement('copyright', $this->copyright); if ($this->license) $xml->writeElement('license', $this->license); $xml->endElement(); // author block $xml->startElement('author'); $xml->writeElement('authorname', $this->authorName); if ($this->authorURL) $xml->writeElement('authorurl', $this->authorURL); $xml->endElement(); // files block $xml->startElement('files'); $xml->writeElement('variables', 'variables.xml'); if ($templates) $xml->writeElement('templates', 'templates.tar'); if ($images) $xml->writeElement('images', 'images.tar', array('path' => $this->imagePath)); $xml->endElement(); // append style info file to style tar $styleTar->addString(self::INFO_FILE, $xml->endDocument()); unset($string); // create variable list $xml->beginDocument('variables', 'http://www.woltlab.com', 'http://www.woltlab.com/XSD/maelstrom/styleVariables.xsd'); // get variables $sql = "SELECT variable.variableName, value.variableValue FROM wcf".WCF_N."_style_variable_value value LEFT JOIN wcf".WCF_N."_style_variable variable ON (variable.variableID = value.variableID) WHERE value.styleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->styleID)); while ($row = $statement->fetchArray()) { $xml->writeElement('variable', $row['variableValue'], array('name' => $row['variableName'])); } // append variable list to style tar $styleTar->addString('variables.xml', $xml->endDocument()); unset($string); if ($templates && $this->templateGroupID) { $templateGroup = new TemplateGroup($this->templateGroupID); // create templates tar $templatesTarName = FileUtil::getTemporaryFilename('templates', '.tar'); $templatesTar = new TarWriter($templatesTarName); @chmod($templatesTarName, 0777); // append templates to tar // get templates $sql = "SELECT template.*, package.package, package.packageDir FROM wcf".WCF_N."_template template LEFT JOIN wcf".WCF_N."_package package ON (package.packageID = template.packageID) WHERE template.templateGroupID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->templateGroupID)); while ($row = $statement->fetchArray()) { $packageDir = 'com.woltlab.wcf'; if (!empty($row['packageDir'])) $packageDir = $row['package']; $filename = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir'] . 'templates/' . $templateGroup->templateGroupFolderName)) . $row['templateName'] . '.tpl'; $templatesTar->add($filename, $packageDir, dirname($filename)); } // append templates tar to style tar $templatesTar->create(); $styleTar->add($templatesTarName, 'templates.tar', $templatesTarName); @unlink($templatesTarName); } if ($images && ($this->imagePath && $this->imagePath != 'images/')) { // create images tar $imagesTarName = FileUtil::getTemporaryFilename('images_', '.tar'); $imagesTar = new TarWriter($imagesTarName); @chmod($imagesTarName, 0777); // append images to tar $path = FileUtil::addTrailingSlash(WCF_DIR.$this->imagePath); if (file_exists($path) && is_dir($path)) { $handle = opendir($path); $regEx = new Regex('\.(jpg|jpeg|gif|png|svg)$', Regex::CASE_INSENSITIVE); while (($file = readdir($handle)) !== false) { if (is_file($path.$file) && $regEx->match($file)) { $imagesTar->add($path.$file, '', $path); } } } // append images tar to style tar $imagesTar->create(); $styleTar->add($imagesTarName, 'images.tar', $imagesTarName); @unlink($imagesTarName); } // output file content $styleTar->create(); // export as style package if (empty($packageName)) { readfile($styleTarName); } else { // export as package // create package tar $packageTarName = FileUtil::getTemporaryFilename('package_', '.tar.gz'); $packageTar = new TarWriter($packageTarName, true); // append style tar $styleTarName = FileUtil::unifyDirSeperator($styleTarName); $packageTar->add($styleTarName, '', FileUtil::addTrailingSlash(dirname($styleTarName))); // create package.xml $xml->beginDocument('package', 'http://www.woltlab.com', 'http://www.woltlab.com/XSD/maelstrom/package.xsd', array('name' => $packageName)); $xml->startElement('packageinformation'); $xml->writeElement('packagename', $this->styleName); // description foreach ($styleDescriptions as $languageCode => $value) { $xml->writeElement('packagedescription', $value, array('language' => $languageCode)); } $xml->writeElement('version', $this->styleVersion); $xml->writeElement('date', $this->styleDate); $xml->endElement(); $xml->startElement('authorinformation'); $xml->writeElement('author', $this->authorName); if ($this->authorURL) $xml->writeElement('authorurl', $this->authorURL); $xml->endElement(); $xml->startElement('instructions', array('type' => 'install')); $xml->writeElement('instruction', basename($styleTarName), array('type' => 'style')); $xml->endElement(); // append package info file to package tar $packageTar->addString(PackageArchive::INFO_FILE, $xml->endDocument()); $packageTar->create(); readfile($packageTarName); @unlink($packageTarName); } @unlink($styleTarName); }
/** * @see wcf\form\IForm::validate() */ public function validate() { parent::validate(); if (empty($this->authorName)) { throw new UserInputException('authorName'); } // validate date if (empty($this->styleDate)) { throw new UserInputException('styleDate'); } else { try { DateUtil::validateDate($this->styleDate); } catch (SystemException $e) { throw new UserInputException('styleDate', 'notValid'); } } if (empty($this->styleName)) { throw new UserInputException('styleName'); } // validate version if (empty($this->styleVersion)) { throw new UserInputException('styleVersion'); } else if (!Package::isValidVersion($this->styleVersion)) { throw new UserInputException('styleVersion', 'notValid'); } // validate style description if (!I18nHandler::getInstance()->validateValue('styleDescription', true, true)) { throw new UserInputException('styleDescription'); } // validate template group id if ($this->templateGroupID) { if (!isset($this->availableTemplateGroups[$this->templateGroupID])) { throw new UserInputException('templateGroupID'); } } // ensure image path is below WCF_DIR/images/ if ($this->imagePath) { $relativePath = FileUtil::unifyDirSeperator(FileUtil::getRelativePath(WCF_DIR.'images/', WCF_DIR.$this->imagePath)); if (strpos($relativePath, '../') !== false) { throw new UserInputException('imagePath', 'notValid'); } } if (!empty($this->variables['overrideLess'])) { $this->parseOverrides(); } }
/** * Scans the given dir for installed files. * * @param string $dir */ protected function getInstalledFiles($dir) { if ($files = glob($dir . '*')) { foreach ($files as $file) { if (is_dir($file)) { $this->getInstalledFiles(FileUtil::addTrailingSlash($file)); } else { self::$installedFiles[] = FileUtil::unifyDirSeperator($file); } } } }
/** * @see wcf\page\IPage::readData() */ public function readData() { parent::readData(); // init cache data $this->cacheData = array( 'source' => get_class(CacheHandler::getInstance()->getCacheSource()), 'version' => '', 'size' => 0, 'files' => 0 ); switch ($this->cacheData['source']) { case 'wcf\system\cache\source\DiskCacheSource': // set version $this->cacheData['version'] = WCF_VERSION; // get package dirs $sql = "SELECT packageDir FROM wcf".WCF_N."_package WHERE isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(1)); while ($row = $statement->fetchArray()) { $packageDir = FileUtil::getRealPath(WCF_DIR.$row['packageDir']); $this->readCacheFiles('data', $packageDir.'cache'); } break; case 'wcf\system\cache\source\MemcachedCacheSource': // set version $this->cacheData['version'] = WCF_VERSION; // get package dirs $sql = "SELECT packageDir FROM wcf".WCF_N."_package WHERE isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(1)); while ($row = $statement->fetchArray()) { $packageDir = FileUtil::getRealPath(WCF_DIR.$row['packageDir']); $this->readCacheFiles('data', $packageDir.'cache'); } break; case 'wcf\system\cache\source\ApcCacheSource': // set version $this->cacheData['version'] = phpversion('apc'); // get package dirs $sql = "SELECT packageDir, packageName FROM wcf".WCF_N."_package WHERE isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(1)); $packageNames = array(); while ($row = $statement->fetchArray()) { $packagePath = FileUtil::getRealPath(WCF_DIR.$row['packageDir']).'cache/'; $packageNames[$packagePath] = $row['packageName']; } $apcinfo = apc_cache_info('user'); $cacheList = $apcinfo['cache_list']; foreach ($cacheList as $cache) { $cachePath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator(dirname($cache['info']))); if (isset($packageNames[$cachePath])) { // Use the packageName + the instance number, because pathes could confuse the administrator. // He could think this is a file cache. If instanceName would be unique, we could use it instead. $packageName = $packageNames[$cachePath]; if (!isset($this->caches['data'])) { $this->caches['data'] = array(); } if (!isset($this->caches['data'][$packageName])) { $this->caches['data'][$packageName] = array(); } // get additional cache information $this->caches['data'][$packageName][] = array( 'filename' => basename($cache['info'], '.php'), 'filesize' => $cache['mem_size'], 'mtime' => $cache['mtime'], ); $this->cacheData['files']++; $this->cacheData['size'] += $cache['mem_size']; } } break; case 'wcf\system\cache\source\NoCacheSource': $this->cacheData['version'] = WCF_VERSION; $this->cacheData['files'] = $this->cacheData['size'] = 0; break; } $this->readCacheFiles('language', FileUtil::unifyDirSeperator(WCF_DIR.'language')); $this->readCacheFiles('template', FileUtil::unifyDirSeperator(WCF_DIR.'templates/compiled'), new Regex('\.meta\.php$')); $this->readCacheFiles('template', FileUtil::unifyDirSeperator(WCF_DIR.'acp/templates/compiled'), new Regex('\.meta\.php$')); $this->readCacheFiles('style', FileUtil::unifyDirSeperator(WCF_DIR.'style'), null, 'css'); $this->readCacheFiles('style', FileUtil::unifyDirSeperator(WCF_DIR.'acp/style'), new Regex('WCFSetup.css$'), 'css'); }
/** * Adds a file to the tar archive. * * @param string $filename * @param string $addDir * @param string $removeDir * @return boolean result */ protected function addFile($filename, $addDir, $removeDir) { $filename = FileUtil::unifyDirSeperator($filename); $storedFilename = $filename; if (!empty($removeDir)) $storedFilename = StringUtil::replaceIgnoreCase($removeDir, '', $filename); if (!empty($addDir)) $storedFilename = $addDir . $storedFilename; if (is_file($filename)) { // open file $file = new File($filename, 'rb'); // write header if (!$this->writeFileHeader($filename, $storedFilename)) { return false; } // write file content while (($buffer = $file->read(512)) != '') { $this->file->write(pack('a512', $buffer)); } // close file $file->close(); } else { // only directory header if (!$this->writeFileHeader($filename, $storedFilename)) { return false; } } return true; }
/** * @see wcf\page\IPage::readData() */ public function readData() { parent::readData(); // init cache data $this->cacheData = array('source' => get_class(CacheHandler::getInstance()->getCacheSource()), 'version' => '', 'size' => 0, 'files' => 0); $_this = $this; $readFileCache = function ($cacheDir, Regex $ignore = null) use($_this) { $_this->caches[$cacheDir] = array(); // get files in cache directory try { $directoryUtil = DirectoryUtil::getInstance($cacheDir); } catch (SystemException $e) { return; } $files = $directoryUtil->getFileObjects(SORT_ASC, new Regex('\\.php$')); // get additional file information if (is_array($files)) { foreach ($files as $file) { if ($ignore !== null) { if ($ignore->match($file)) { continue; } } $_this->caches[$cacheDir][] = array('filename' => $file->getBasename(), 'filesize' => $file->getSize(), 'mtime' => $file->getMtime(), 'perm' => substr(sprintf('%o', $file->getPerms()), -3), 'writable' => $file->isWritable()); $_this->cacheData['files']++; $_this->cacheData['size'] += $file->getSize(); } } }; // filesystem cache if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\DiskCacheSource') { // set version $this->cacheData['version'] = WCF_VERSION; $conditions = new PreparedStatementConditionBuilder(); $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies())); $conditions->add("isApplication = ?", array(1)); // get package dirs $sql = "SELECT\tpackageDir\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t" . $conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); while ($row = $statement->fetchArray()) { $packageDir = FileUtil::getRealPath(WCF_DIR . $row['packageDir']); $readFileCache($packageDir . 'cache'); } } else { if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\MemcacheCacheSource') { // get version $this->cacheData['version'] = MemcacheAdapter::getInstance()->getMemcache()->getVersion(); // get stats $stats = MemcacheAdapter::getInstance()->getMemcache()->getStats(); $this->cacheData['files'] = $stats['curr_items']; $this->cacheData['size'] = $stats['bytes']; } else { if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\ApcCacheSource') { // set version $this->cacheData['version'] = phpversion('apc'); $conditions = new PreparedStatementConditionBuilder(); $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies())); $conditions->add("isApplication = ?", array(1)); // get package dirs $sql = "SELECT\tpackageDir, packageName, instanceNo\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t" . $conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); $packageNames = array(); while ($row = $statement->fetchArray()) { $packagePath = FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . 'cache/'; $packageNames[$packagePath] = $row['packageName'] . ' #' . $row['instanceNo']; } $apcinfo = apc_cache_info('user'); $cacheList = $apcinfo['cache_list']; foreach ($cacheList as $cache) { $cachePath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator(dirname($cache['info']))); if (isset($packageNames[$cachePath])) { // Use the packageName + the instance number, because pathes could confuse the administrator. // He could think this is a file cache. If instanceName would be unique, we could use it instead. $packageName = $packageNames[$cachePath]; if (!isset($this->caches[$packageName])) { $this->caches[$packageName] = array(); } // get additional cache information $this->caches[$packageName][] = array('filename' => basename($cache['info'], '.php'), 'filesize' => $cache['mem_size'], 'mtime' => $cache['mtime']); $this->cacheData['files']++; $this->cacheData['size'] += $cache['mem_size']; } } } else { if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\NoCacheSource') { $this->cacheData['version'] = WCF_VERSION; $this->cacheData['files'] = $this->cacheData['size'] = 0; } } } } $readFileCache(WCF_DIR . 'language'); $readFileCache(WCF_DIR . 'templates/compiled', new Regex('\\.meta\\.php$')); $readFileCache(WCF_DIR . 'acp/templates/compiled', new Regex('\\.meta\\.php$')); }
/** * @see wcf\system\cache\source\ICacheSource::clear() */ public function clear($directory, $filepattern) { // unify parameters $directory = FileUtil::unifyDirSeperator($directory); $filepattern = FileUtil::unifyDirSeperator($filepattern); $filepattern = str_replace('*', '.*', str_replace('.', '\\.', $filepattern)); if (substr($directory, -1) != '/') { $directory .= '/'; } DirectoryUtil::getInstance($directory)->executeCallback(new Callback(function ($filename) { if (!@touch($filename, 1)) { @unlink($filename); } }), new Regex('^' . $directory . $filepattern . '$', Regex::CASE_INSENSITIVE)); }
protected static function getIconFiles($path, $extension = 'svg') { $files = array(); if (is_dir($path)) { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path)); foreach ($iterator as $file) { if (preg_match('/\\.' . $extension . '$/', $file->getFilename())) { $files[] = FileUtil::unifyDirSeperator($file->getPathname()); } } } return $files; }