/** * * Write out a series of dirs and symlinks for a new Vendor source. * * @param string $vendor The Vendor name. * * @return void * */ protected function _exec($vendor = null) { // we need a vendor name, at least if (!$vendor) { throw $this->_exception('ERR_NO_VENDOR'); } $this->_outln("Making links for vendor '{$vendor}' ..."); // build "foo-bar" and "FooBar" versions of the vendor name. $this->_inflect = Solar_Registry::get('inflect'); $this->_dashes = $this->_inflect->camelToDashes($vendor); $this->_studly = $this->_inflect->dashesToStudly($this->_dashes); $links = array(array('dir' => "include", 'tgt' => $this->_studly, 'src' => "../source/{$this->_dashes}/{$this->_studly}"), array('dir' => "include/Test", 'tgt' => $this->_studly, 'src' => "../../source/{$this->_dashes}/tests/Test/{$this->_studly}"), array('dir' => "include/Mock", 'tgt' => $this->_studly, 'src' => "../../source/{$this->_dashes}/tests/Mock/{$this->_studly}"), array('dir' => "include/Fixture", 'tgt' => $this->_studly, 'src' => "../../source/{$this->_dashes}/tests/Fixture/{$this->_studly}"), array('dir' => "script", 'tgt' => $this->_dashes, 'src' => "../source/solar/script/solar")); $system = Solar::$system; foreach ($links as $link) { // $dir, $src, $tgt extract($link); // make it $this->_out(" Making link '{$dir}/{$tgt}' ... "); try { Solar_Symlink::make($src, $tgt, "{$system}/{$dir}"); $this->_outln("done."); } catch (Exception $e) { $this->_out($e->getMessage()); $this->_outln(" ... failed."); } } // done with this part $this->_outln("... done."); // make public links $link_public = Solar::factory('Solar_Cli_LinkPublic'); $link_public->exec($vendor); // done for real $this->_outln("Remember to add '{$this->_studly}_App' to the " . "['Solar_Controller_Front']['classes'] element " . "in your config file so that it finds your apps."); $this->_outln("Remember to add '{$this->_studly}_Model' to the " . "['Solar_Sql_Model_Catalog']['classes'] element " . "in your config file so that it finds your models."); }
/** * * Creates a symlink in "docroot/public" for a given class. * * @param string $class The class name. * * @return void * */ protected function _link($class) { // array of class-name parts $arr = explode('_', $class); // the last part of the class name where to put the symlink $tgt = array_pop($arr); // make the rest of the array into a subdirectory path $sub = implode('/', $arr); // where is the source (original) directory located, relatively? $k = count($arr); $src = ""; for ($i = 0; $i < $k; $i++) { $src .= "../"; } $src .= "../../include/{$sub}/{$tgt}/Public"; // need the system root $system = Solar::$system; // make sure we have a place to make the symlink $dir = "docroot/public/{$sub}"; if (!Solar_Dir::exists("{$system}/{$dir}")) { $this->_out(" Making public directory {$dir} ... "); Solar_Dir::mkdir("{$system}/{$dir}", 0755, true); $this->_outln("done."); } // make the symlink $this->_out(" Making public symlink for {$class} ... "); try { Solar_Symlink::make($src, $tgt, $dir); $this->_outln('done.'); } catch (Exception $e) { $this->_out($e->getMessage()); $this->_outln(' ... failed.'); } }
/** * * Makes a symbolic link to a file or directory. * * @param string $src The source path of the real file or directory. * * @param string $tgt The target path for where to put the symlink. * * @param string $dir Change to this directory before creating the * symlink, typically the target directory; this helps when making * relative symlinks. * * @return string The last line from the [[php::exec() | ]] call to * create the symlink. * */ public static function make($src, $tgt, $dir = null) { // are we on a windows system prior to NT6? $is_win = strtolower(substr(PHP_OS, 0, 3)) == 'win'; if ($is_win && php_uname('r') < 6) { throw Solar_Symlink::_exception('ERR_WINDOWS_VERSION'); } // massage the change-dir a bit $dir = trim($dir); if ($dir) { $dir = Solar_Dir::fix($dir); } // is the source a directory or a file? $path = $dir . $src; $is_dir = Solar_Dir::exists($path); $is_file = Solar_File::exists($path); if (!$is_dir && !$is_file) { // no source found throw Solar_Symlink::_exception('ERR_SOURCE_NOT_FOUND', array('src' => $src, 'tgt' => $tgt, 'dir' => $dir, 'path' => $path)); } // find any existing path to the target if ($is_dir) { $path = Solar_Dir::exists($dir . $tgt); } else { $path = Solar_File::exists($dir . $tgt); } // does the target exist already? if ($path) { throw Solar_Symlink::_exception('ERR_TARGET_EXISTS', array('src' => $src, 'tgt' => $tgt, 'dir' => $dir, 'path' => $path)); } // escape arguments for the command $src = escapeshellarg($src); $tgt = escapeshellarg($tgt); $dir = escapeshellarg($dir); if ($is_win && $is_dir) { // windows directory return Solar_Symlink::_makeWinDir($src, $tgt, $dir); } elseif ($is_win && $is_file) { // windows file return Solar_Symlink::_makeWinFile($src, $tgt, $dir); } else { // non-windows return Solar_Symlink::_make($src, $tgt, $dir); } }
/** * * Write out a series of dirs and symlinks for a new Vendor source. * * @param string $vendor The Vendor name. * * @return void * */ protected function _exec($vendor = null) { // we need a vendor name, at least if (!$vendor) { throw $this->_exception('ERR_NO_VENDOR'); } $this->_outln("Removing links for vendor '{$vendor}' ..."); // build "foo-bar" and "FooBar" versions of the vendor name. $this->_inflect = Solar_Registry::get('inflect'); $this->_dashes = $this->_inflect->camelToDashes($vendor); $this->_studly = $this->_inflect->dashesToStudly($this->_dashes); // the base system dir $system = Solar::$system; // the links to remove (reverse order from make-vendor) $links = array("script/{$this->_dashes}", "include/Fixture/{$this->_studly}", "include/Mock/{$this->_studly}", "include/Test/{$this->_studly}", "include/{$this->_studly}"); // remove the links foreach ($links as $link) { $this->_out(" Removing '{$link}' ... "); $path = "{$system}/{$link}"; // fix for windows $path = str_replace('/', DIRECTORY_SEPARATOR, $path); if (Solar_File::exists($path) || Solar_Dir::exists($path)) { Solar_Symlink::remove($path); $this->_outln("done."); } else { $this->_outln("missing."); } } // done! $this->_outln("... done."); // reminders $this->_outln("Remember to remove '{$this->_studly}_App' from the " . "['Solar_Controller_Front']['classes'] element " . "in your config file."); $this->_outln("Remember to remove '{$this->_studly}_Model' from the " . "['Solar_Sql_Model_Catalog']['classes'] element " . "in your config file."); // need to write a recursive-remove method for Solar_Dir that will // delete only the symlinked files (not the real files) $this->_outln("You will need to remove the " . "'docroot/public/{$this->_studly}' directory yourself, as it " . "may contain copies of public assets (not links)."); }
/** * * Removes a file or directory symbolic link. * * Actually, this will remove the file or directory even if it's not * a symbolic link, so be careful with it. * * @param string $path The symbolic link to remove. * * @return void * */ public static function remove($path) { // are we on a windows system prior to NT6? $is_win = strtolower(substr(PHP_OS, 0, 3)) == 'win'; if ($is_win && php_uname('r') < 6) { throw Solar_Symlink::_exception('ERR_WINDOWS_VERSION'); } // does the path exist for removal? $is_dir = Solar_Dir::exists($path); $is_file = Solar_File::exists($path); if (!$is_dir && !$is_file) { throw Solar_Symlink::_exception('ERR_PATH_NOT_FOUND', array('path' => $path)); } // how to remove? if ($is_win) { // have to double up on removals because windows reports all // symlinks as files, even if they point to dirs. @unlink($path); Solar_Dir::rmdir($path); } else { // unix file or dir @unlink($path); } }