/** * Find the paths to all the installed shell themes in the app. * * Bake themes are directories not named `skel` inside a `Console/Templates` path. * They are listed in this order: app -> plugin -> default * * @return array Array of bake themes that are installed. */ protected function _findThemes() { $paths = App::path('Console'); $plugins = App::objects('plugin'); foreach ($plugins as $plugin) { $paths[] = $this->_pluginPath($plugin) . 'Console/'; } $core = current(App::core('Console')); $Folder = new Folder($core . 'Templates/default'); $contents = $Folder->read(); $themeFolders = $contents[0]; $paths[] = $core; foreach ($paths as $i => $path) { $paths[$i] = rtrim($path, DS) . DS; } $this->_io->verbose('Found the following bake themes:'); $themes = []; foreach ($paths as $path) { $Folder = new Folder($path . 'Templates', false); $contents = $Folder->read(); $subDirs = $contents[0]; foreach ($subDirs as $dir) { $Folder = new Folder($path . 'Templates/' . $dir); $contents = $Folder->read(); $subDirs = $contents[0]; if (array_intersect($contents[0], $themeFolders)) { $templateDir = $path . 'Templates/' . $dir . DS; $themes[$dir] = $templateDir; $this->_io->verbose(sprintf("- %s -> %s", $dir, $templateDir)); } } } return $themes; }
/** * tearDown method * * @return void */ public function tearDown() { parent::tearDown(); $Folder = new Folder($this->Task->path . 'BakeTestApp'); $Folder->delete(); unset($this->Task); }
/** * tearDown method * * @return void */ public function tearDown() { parent::tearDown(); unset($this->Task); $Folder = new Folder($this->path); $Folder->delete(); Plugin::unload(); }
/** * tearDown method * * @return void */ public function tearDown() { parent::tearDown(); $this->File->close(); unset($this->File); $Folder = new Folder(); $Folder->delete(TMP . 'tests/permissions'); }
/** * Recursively adds all the files in a directory to the test suite. * * @param string $directory The directory subtree to add tests from. * @return void */ public function addTestDirectoryRecursive($directory = '.') { $Folder = new Folder($directory); $files = $Folder->tree(null, true, 'files'); foreach ($files as $file) { if (substr($file, -4) === '.php') { $this->addTestFile($file); } } }
/** * testAddTestDirectoryRecursiveWithNonPhp * * @return void */ public function testAddTestDirectoryRecursiveWithNonPhp() { $this->skipIf(!is_writable(TMP), 'Cant addTestDirectoryRecursiveWithNonPhp unless the tmp folder is writable.'); $Folder = new Folder(TMP . 'MyTestFolder', true, 0777); touch($Folder->path . DS . 'BackupTest.php~'); touch($Folder->path . DS . 'SomeNotesTest.txt'); touch($Folder->path . DS . 'NotHiddenTest.php'); $suite = $this->getMock('Cake\\TestSuite\\TestSuite', array('addTestFile')); $suite->expects($this->exactly(1))->method('addTestFile'); $suite->addTestDirectoryRecursive($Folder->pwd()); $Folder->delete(); }
/** * Checks that given project path does not already exist, and * finds the app directory in it. Then it calls bake() with that information. * * @return mixed */ public function main() { $project = null; if (isset($this->args[0])) { $project = $this->args[0]; } else { $appContents = array_diff(scandir(APP), ['.', '..']); if (empty($appContents)) { $suggestedPath = rtrim(APP, DS); } else { $suggestedPath = APP . 'MyApp'; } } while (!$project) { $prompt = __d('cake_console', 'What is the path to the project you want to bake?'); $project = $this->in($prompt, null, $suggestedPath); } $namespace = basename($project); if (!preg_match('/^\\w[\\w\\d_]+$/', $namespace)) { $this->err(__d('cake_console', 'Project Name/Namespace needs to start with a letter and can only contain letters, digits and underscore')); $this->args = []; return $this->execute(); } if ($project && !Folder::isAbsolute($project) && isset($_SERVER['PWD'])) { $project = $_SERVER['PWD'] . DS . $project; } $response = false; while (!$response && is_dir($project) === true && file_exists($project . 'Config' . 'boostrap.php')) { $prompt = __d('cake_console', '<warning>A project already exists in this location:</warning> %s Overwrite?', $project); $response = $this->in($prompt, ['y', 'n'], 'n'); if (strtolower($response) === 'n') { $response = $project = false; } } if ($project === false) { $this->out(__d('cake_console', 'Aborting project creation.')); return; } if ($this->bake($project)) { $this->out(__d('cake_console', '<success>Project baked successfully!</success>')); return $path; } }
/** * Test Execute * * @return void */ public function testExecuteWithOneArg() { $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y')); $path = $this->Task->path . 'BakeTestPlugin'; $file = $path . DS . 'Controller' . DS . 'AppController.php'; $this->Task->expects($this->at(1))->method('createFile')->with($file, $this->stringContains('class AppController extends BaseController {')); $file = $path . DS . 'phpunit.xml'; $this->Task->expects($this->at(2))->method('createFile')->with($file, new \PHPUnit_Framework_Constraint_IsAnything()); $file = $path . DS . 'Test' . DS . 'bootstrap.php'; $this->Task->expects($this->at(3))->method('createFile')->with($file, new \PHPUnit_Framework_Constraint_IsAnything()); $this->Task->main('BakeTestPlugin'); $Folder = new Folder($this->Task->path . 'BakeTestPlugin'); $Folder->delete(); }
/** * Search files that may contain translatable strings * * @return void */ protected function _searchFiles() { $pattern = false; if (!empty($this->_exclude)) { $exclude = []; foreach ($this->_exclude as $e) { if (DS !== '\\' && $e[0] !== DS) { $e = DS . $e; } $exclude[] = preg_quote($e, '/'); } $pattern = '/' . implode('|', $exclude) . '/'; } foreach ($this->_paths as $path) { $Folder = new Folder($path); $files = $Folder->findRecursive('.*\\.(php|ctp|thtml|inc|tpl)', true); if (!empty($pattern)) { foreach ($files as $i => $file) { if (preg_match($pattern, $file)) { unset($files[$i]); } } $files = array_values($files); } $this->_files = array_merge($this->_files, $files); } }
/** * setUp method * * @return void */ public function setUp() { parent::setUp(); $this->io = $this->getMock('Cake\\Console\\ConsoleIo', [], [], '', false); $this->Shell = new ShellTestShell($this->io); if (is_dir(TMP . 'shell_test')) { $Folder = new Folder(TMP . 'shell_test'); $Folder->delete(); } }
/** * test item() with enclosure data. * * @return void */ public function testItemEnclosureLength() { if (!is_writable(WWW_ROOT)) { $this->markTestSkipped('Webroot is not writable.'); } $testExists = is_dir(WWW_ROOT . 'tests'); $tmpFile = WWW_ROOT . 'tests/cakephp.file.test.tmp'; $File = new File($tmpFile, true); $this->assertTrue($File->write('123'), 'Could not write to ' . $tmpFile); clearstatcache(); $item = array('title' => array('value' => 'My Title', 'cdata' => true), 'link' => 'http://www.example.com/1', 'description' => array('value' => 'descriptive words', 'cdata' => true), 'enclosure' => array('url' => '/tests/cakephp.file.test.tmp'), 'pubDate' => '2008-05-31 12:00:00', 'guid' => 'http://www.example.com/1', 'category' => array(array('value' => 'CakePHP', 'cdata' => true, 'domain' => 'http://www.cakephp.org'), array('value' => 'Bakery', 'cdata' => true))); $result = $this->Rss->item(null, $item); if (!function_exists('mime_content_type')) { $type = null; } else { $type = mime_content_type($tmpFile); } $expected = array('<item', '<title', '<![CDATA[My Title]]', '/title', '<link', 'http://www.example.com/1', '/link', '<description', '<![CDATA[descriptive words]]', '/description', 'enclosure' => array('url' => $this->Rss->url('/tests/cakephp.file.test.tmp', true), 'length' => filesize($tmpFile), 'type' => $type), '<pubDate', date('r', strtotime('2008-05-31 12:00:00')), '/pubDate', '<guid', 'http://www.example.com/1', '/guid', 'category' => array('domain' => 'http://www.cakephp.org'), '<![CDATA[CakePHP]]', '/category', '<category', '<![CDATA[Bakery]]', '/category', '/item'); if ($type === null) { unset($expected['enclosure']['type']); } $this->assertTags($result, $expected); $File->delete(); if (!$testExists) { $Folder = new Folder(WWW_ROOT . 'tests'); $Folder->delete(); } }
/** * testMoveWithSkip method * * Verify that directories and files are moved recursively * even if the destination directory already exists. * Subdirectories existing in both destination and source directory * are skipped and not merged or overwritten. * * @return void */ public function testMoveWithSkip() { extract($this->_setupFilesystem()); $Folder = new Folder($folderOne); $result = $Folder->move(array('to' => $folderTwo, 'scheme' => Folder::SKIP)); $this->assertTrue($result); $this->assertTrue(file_exists($folderTwo . '/file1.php')); $this->assertTrue(is_dir($folderTwo . '/folderB')); $this->assertTrue(file_exists($folderTwoB . '/fileB.php')); $this->assertFalse(file_exists($fileOne)); $this->assertFalse(file_exists($folderOneA)); $this->assertFalse(file_exists($fileOneA)); $Folder = new Folder($folderTwo); $Folder->delete(); new Folder($folderOne, true); new Folder($folderOneA, true); new Folder($folderTwo, true); touch($fileOne); touch($fileOneA); $Folder = new Folder($folderOne); $result = $Folder->move(array('to' => $folderTwo, 'scheme' => Folder::SKIP)); $this->assertTrue($result); $this->assertTrue(file_exists($folderTwo . '/file1.php')); $this->assertTrue(is_dir($folderTwo . '/folderA')); $this->assertTrue(file_exists($folderTwo . '/folderA/fileA.php')); $this->assertFalse(file_exists($fileOne)); $this->assertFalse(file_exists($folderOneA)); $this->assertFalse(file_exists($fileOneA)); $Folder = new Folder($folderTwo); $Folder->delete(); new Folder($folderOne, true); new Folder($folderOneA, true); new Folder($folderTwo, true); new Folder($folderTwoB, true); touch($fileOne); touch($fileOneA); file_put_contents($folderTwoB . '/fileB.php', 'untouched'); $Folder = new Folder($folderOne); $result = $Folder->move(array('to' => $folderTwo, 'scheme' => Folder::SKIP)); $this->assertTrue($result); $this->assertTrue(file_exists($folderTwo . '/file1.php')); $this->assertEquals('untouched', file_get_contents($folderTwoB . '/fileB.php')); $this->assertFalse(file_exists($fileOne)); $this->assertFalse(file_exists($folderOneA)); $this->assertFalse(file_exists($fileOneA)); $Folder = new Folder($path); $Folder->delete(); }
/** * test fileExistsInPath() * * @return void */ public function testFileExistsInPath() { if (!function_exists('ini_set')) { $this->markTestSkipped('%s ini_set function not available'); } $_includePath = ini_get('include_path'); $path = TMP . 'basics_test'; $folder1 = $path . DS . 'folder1'; $folder2 = $path . DS . 'folder2'; $file1 = $path . DS . 'file1.php'; $file2 = $folder1 . DS . 'file2.php'; $file3 = $folder1 . DS . 'file3.php'; $file4 = $folder2 . DS . 'file4.php'; new Folder($path, true); new Folder($folder1, true); new Folder($folder2, true); touch($file1); touch($file2); touch($file3); touch($file4); ini_set('include_path', $path . PATH_SEPARATOR . $folder1); $this->assertEquals(fileExistsInPath('file1.php'), $file1); $this->assertEquals(fileExistsInPath('file2.php'), $file2); $this->assertEquals(fileExistsInPath('folder1' . DS . 'file2.php'), $file2); $this->assertEquals(fileExistsInPath($file2), $file2); $this->assertEquals(fileExistsInPath('file3.php'), $file3); $this->assertEquals(fileExistsInPath($file4), $file4); $this->assertFalse(fileExistsInPath('file1')); $this->assertFalse(fileExistsInPath('file4.php')); $Folder = new Folder($path); $Folder->delete(); ini_set('include_path', $_includePath); }
/** * Bake the plugin, create directories and files * * @param string $plugin Name of the plugin in CamelCased format * @return bool */ public function bake($plugin) { $pathOptions = App::path('Plugin'); if (count($pathOptions) > 1) { $this->findPath($pathOptions); } $this->hr(); $this->out(__d('cake_console', "<info>Plugin Name:</info> %s", $plugin)); $this->out(__d('cake_console', "<info>Plugin Directory:</info> %s", $this->path . $plugin)); $this->hr(); $looksGood = $this->in(__d('cake_console', 'Look okay?'), ['y', 'n', 'q'], 'y'); if (strtolower($looksGood) === 'y') { $Folder = new Folder($this->path . $plugin); $directories = ['Config' . DS . 'Schema', 'Model' . DS . 'Behavior', 'Model' . DS . 'Table', 'Model' . DS . 'Entity', 'Console' . DS . 'Command' . DS . 'Task', 'Controller' . DS . 'Component', 'Lib', 'View' . DS . 'Helper', 'Template', 'Test' . DS . 'TestCase' . DS . 'Controller' . DS . 'Component', 'Test' . DS . 'TestCase' . DS . 'View' . DS . 'Helper', 'Test' . DS . 'TestCase' . DS . 'Model' . DS . 'Behavior', 'Test' . DS . 'Fixture', 'webroot']; foreach ($directories as $directory) { $dirPath = $this->path . $plugin . DS . $directory; $Folder->create($dirPath); new File($dirPath . DS . 'empty', true); } foreach ($Folder->messages() as $message) { $this->out($message, 1, Shell::VERBOSE); } $errors = $Folder->errors(); if (!empty($errors)) { foreach ($errors as $message) { $this->error($message); } return false; } $controllerFileName = 'AppController.php'; $out = "<?php\n\n"; $out .= "namespace {$plugin}\\Controller;\n\n"; $out .= "use App\\Controller\\AppController as BaseController;\n\n"; $out .= "class AppController extends BaseController {\n\n"; $out .= "}\n"; $this->createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out); $this->_modifyBootstrap($plugin); $this->_generatePhpunitXml($plugin, $this->path); $this->_generateTestBootstrap($plugin, $this->path); $this->hr(); $this->out(__d('cake_console', '<success>Created:</success> %s in %s', $plugin, $this->path . $plugin), 2); } return true; }
/** * Get the possible classes for a given type. * * @param string $namespace The namespace fragment to look for classes in. * @return array */ protected function _getClassOptions($namespace) { $classes = []; $base = APP; if ($this->plugin) { $base = Plugin::path($this->plugin); } $path = $base . str_replace('\\', DS, $namespace); $folder = new Folder($path); list($dirs, $files) = $folder->read(); foreach ($files as $file) { $classes[] = str_replace('.php', '', $file); } return $classes; }