getRequest(); $console = $this->getServiceLocator()->get('console'); $relativePath = ''; $usingStdout = false; $directory = $request->getParam('directory'); $appending = $request->getParam('append', false) || $request->getParam('a', false); $overwrite = $request->getParam('overwrite', false) || $request->getParam('w', false); // Validate directory if (!is_dir($directory)) { $m = new ConsoleModel(); $m->setErrorLevel(2); $m->setResult('Invalid library directory provided "' . $directory . '"' . PHP_EOL); return $m; } $directory = realpath($directory); // Determine output file name $output = $request->getParam('destination', $directory . '/autoload_classmap.php'); if ('-' == $output) { $output = STDOUT; $usingStdout = true; } elseif (is_dir($output)) { $m = new ConsoleModel(); $m->setErrorLevel(2); $m->setResult('Invalid output file provided' . PHP_EOL); return $m; } elseif (!is_writeable(dirname($output))) { $m = new ConsoleModel(); $m->setErrorLevel(2); $m->setResult("Cannot write to '$output'; aborting." . PHP_EOL); return $m; } elseif (file_exists($output) && !$overwrite && !$appending) { $m = new ConsoleModel(); $m->setErrorLevel(2); $m->setResult( "Autoload file already exists at '$output'," . PHP_EOL . "but 'overwrite' or 'appending' flag was not specified; aborting." . PHP_EOL ); return $m; } else { // We need to add the $libraryPath into the relative path that is created in the classmap file. $classmapPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath(dirname($output))); // Simple case: $libraryPathCompare is in $classmapPathCompare if (strpos($directory, $classmapPath) === 0) { if ($directory !== $classmapPath) { // prevent double dash in filepaths when using "." as directory $relativePath = substr($directory, strlen($classmapPath) + 1) . '/'; } } else { $libraryPathParts = explode('/', $directory); $classmapPathParts = explode('/', $classmapPath); // Find the common part $count = count($classmapPathParts); for ($i = 0; $i < $count; $i++) { if (!isset($libraryPathParts[$i]) || $libraryPathParts[$i] != $classmapPathParts[$i]) { // Common part end break; } } // Add parent dirs for the subdirs of classmap $relativePath = str_repeat('../', $count - $i); // Add library subdirs $count = count($libraryPathParts); for (; $i < $count; $i++) { $relativePath .= $libraryPathParts[$i] . '/'; } } } if (!$usingStdout) { if ($appending) { $console->write('Appending to class file map '); $console->write($output, Color::LIGHT_WHITE); $console->write(' for library in '); $console->writeLine($directory, Color::LIGHT_WHITE); } else { $console->write('Creating classmap file for library in '); $console->writeLine($directory, Color::LIGHT_WHITE); } $console->write('Scanning for files containing PHP classes '); } // Get the ClassFileLocator, and pass it the library path $l = new ClassFileLocator($directory); // Iterate over each element in the path, and create a map of // classname => filename, where the filename is relative to the library path $map = new \stdClass; $count = 0; foreach ($l as $file) { $filename = str_replace($directory . '/', '', str_replace(DIRECTORY_SEPARATOR, '/', $file->getPath()) . '/' . $file->getFilename()); // Add in relative path to library $filename = $relativePath . $filename; foreach ($file->getClasses() as $class) { $map->{$class} = $filename; } $count++; $console->write('.'); } if (!$usingStdout) { $console->writeLine(" DONE", Color::GREEN); $console->write('Found '); $console->write((int)$count, Color::LIGHT_WHITE); $console->writeLine(' PHP classes'); $console->write('Creating classmap code ...'); } // Check if we have found any PHP classes. if (!$count) { $console->writeLine('Cannot find any PHP classes in ' . $directory . '. Aborting!', Color::YELLOW); exit(1); } if ($appending) { $content = var_export((array)$map, true) . ';'; // Prefix with __DIR__; modify the generated content $content = preg_replace("#(=> ')#", "=> __DIR__ . '/", $content); // Fix \' strings from injected DIRECTORY_SEPARATOR usage in iterator_apply op $content = str_replace("\\'", "'", $content); // Convert to an array and remove the first "array(" $content = explode(PHP_EOL, $content); array_shift($content); // Load existing class map file and remove the closing "bracket ");" from it $existing = file($output, FILE_IGNORE_NEW_LINES); array_pop($existing); // Merge $content = implode(PHP_EOL, array_merge($existing, $content)); } else { // Create a file with the class/file map. // Stupid syntax highlighters make separating < from PHP declaration necessary $content = '<' . "?php\n" . "// Generated by Zend Framework 2\n" . 'return ' . var_export((array)$map, true) . ';'; // Prefix with __DIR__; modify the generated content $content = preg_replace("#(=> ')#", "=> __DIR__ . '/", $content); // Fix \' strings from injected DIRECTORY_SEPARATOR usage in iterator_apply op $content = str_replace("\\'", "'", $content); } // Remove unnecessary double-backslashes $content = str_replace('\\\\', '\\', $content); // Exchange "array (" width "array(" $content = str_replace('array (', 'array(', $content); // Align "=>" operators to match coding standard preg_match_all('(\n\s+([^=]+)=>)', $content, $matches, PREG_SET_ORDER); $maxWidth = 0; foreach ($matches as $match) { $maxWidth = max($maxWidth, strlen($match[1])); } $content = preg_replace_callback('(\n\s+([^=]+)=>)', function ($match) use ($maxWidth) { return "\n " . $match[1] . str_repeat(' ', $maxWidth - strlen($match[1])) . '=>'; }, $content); if (!$usingStdout) { $console->writeLine(" DONE" . PHP_EOL, Color::GREEN); $console->write('Writing classmap to '); $console->write($output, Color::LIGHT_WHITE); $console->write('... '); } // Write the contents to disk file_put_contents($output, $content); if (!$usingStdout) { $console->writeLine(" DONE", Color::GREEN); $console->writeLine('Wrote classmap to ' . realpath($output), Color::LIGHT_WHITE); } } }