/** * Create action for the view-spec provider * * @param string $name * @param string $controllerName * @param string $module * @return void */ public function create($name, $controllerName, $module = null) { $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); if (!is_dir('spec')) { throw new ProviderException('Please run zf generate phpspec, to create the environment'); } $response = $this->_registry->getResponse(); $request = $this->_registry->getRequest(); $originalName = $name; $name = LCFirst::apply($name); $camelCaseToDashFilter = new CamelCaseToDash(); $name = strtolower($camelCaseToDashFilter->filter($name)); // alert the user about inline converted names $tense = $request->isPretend() ? 'would be' : 'is'; if ($name !== $originalName) { $response->appendContent('Note: The canonical view name that ' . $tense . ' used with other providers is "' . $name . '";' . ' not "' . $originalName . '" as supplied', array('color' => array('yellow'))); } try { $viewResource = self::createResource($this->_loadedProfile, $name, $controllerName, $module); } catch (Exception $e) { $response->setException($e); return; } // view spec $inflectedController = strtolower($camelCaseToDashFilter->filter($controllerName)); $viewPath = str_replace(basename($viewResource->getContext()->getPath()), '', $viewResource->getContext()->getPath()); $basePath = str_replace("application/views/scripts/{$inflectedController}", '', $viewPath); $specNameFilter = new DashToCamelCase(); $specName = UCFirst::apply($specNameFilter->filter($name)); $moduleController = $inflectedController; if ($module !== null) { $moduleController .= strtolower($camelCaseToDashFilter->filter($module)); } $viewSpecPath = realpath($basePath . '/spec/views') . '/' . $moduleController . '/' . $specName . 'Spec.php'; $specContent = $this->_getSpecContent($name, $controllerName, $module); if ($request->isPretend()) { $response->appendContent('Would create a view script in location ' . $viewResource->getContext()->getPath()); $response->appendContent('Would create a spec at ' . $viewSpecPath); } else { $response->appendContent('Creating a view script in location ' . $viewResource->getContext()->getPath()); $viewResource->create(); $response->appendContent('Creating a spec at ' . $viewSpecPath); if (!is_dir($basePath . '/spec/views')) { mkdir($basePath . '/spec/views'); } if (!is_dir($basePath . '/spec/views/' . $inflectedController)) { mkdir($basePath . '/spec/views/' . $inflectedController); } file_put_contents($viewSpecPath, $specContent); } }
/** * Implements the create action for the action-spec provider * * @param string $name * @param string $controllerName * @param string $module * @return void */ public function create($name, $controllerName, $module = null) { $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION); if (!is_dir('spec')) { throw new ProviderException('Please run zf generate phpspec, to create the environment'); } $response = $this->_registry->getResponse(); $request = $this->_registry->getRequest(); $originalName = $name; $name = LCFirst::apply($name); $camelCaseToDashFilter = new CamelCaseToDash(); $name = strtolower($camelCaseToDashFilter->filter($name)); // alert the user about inline converted names $tense = $request->isPretend() ? 'would be' : 'is'; if ($name !== $originalName) { $response->appendContent('Note: The canonical action name that ' . $tense . ' used with other providers is "' . $name . '";' . ' not "' . $originalName . '" as supplied', array('color' => array('yellow'))); } try { $controllerResource = ControllerProvider::createResource($this->_loadedProfile, $controllerName, $module); $actionResource = self::createResource($this->_loadedProfile, $name, $controllerName, $module); } catch (Exception $e) { $response->setException($e); return; } // action spec $controllerPath = str_replace(basename($controllerResource->getContext()->getPath()), '', $controllerResource->getContext()->getPath()); $basePath = realpath($controllerPath . '/../..'); $controllerSpecPath = realpath($basePath . '/spec/controllers') . '/' . $controllerName . 'ControllerSpec.php'; $specContent = $this->_getSpecContent($name, $controllerName); if ($request->isPretend()) { $response->appendContent('Would create an action named ' . $name . ' inside controller at ' . $controllerResource->getContext()->getPath()); $response->appendContent('Would create an action spec at ' . $controllerSpecPath); } else { $response->appendContent('Creating an action named ' . $name . ' inside controller at ' . $controllerResource->getContext()->getPath()); $actionResource->create(); $response->appendContent('Creating an action spec at ' . $controllerSpecPath); $content = file_get_contents($controllerSpecPath); file_put_contents($controllerSpecPath, str_replace("\n}", $specContent, $content)); } }
/** * Creates mapper content * * @param string $name * @return string */ protected function _getMapperContent($name) { $property = LCFirst::apply($name); $tableName = Pluralize::apply($name); return <<<MAPPER <?php use Application_Model_{$name} as {$name}; use Application_Model_DbTable_{$tableName} as {$tableName}Dao; class Application_Model_{$name}Mapper { /** * Data access object. Typically a db table, but can be any data provider * object. */ protected \$_{$property}Dao; /** * Gets the data access object */ protected function getDao() { if (\$this->_{$property}Dao === null) { \$this->_{$property}Dao = new {$tableName}Dao; } return \$this->_{$property}Dao; } /** * Sets the data access object (for tests purposes) * */ protected function setDao(\$dao) { \$this->_{$property}Dao = \$dao; } /** * Retrives a model given entity primary key value */ public function find(\$primaryKey) { \$records = \$this->getDao()->find(\$primaryKey); if (count(\$records)) { return {$name}::create(\$records->current()->toArray()); } } /** * Retrives a collection (using arrays) given a condition, order, count * and offset */ public function fetchAll( \$condition = null, \$order = null, \$count = null, \$offset = null) { \$records = \$this->getDao()->fetchAll( \$condition, \$order, \$count, \$offset ); \${$property}s = array(); while (\$records->valid()) { \${$property}s[] = {$name}::create(\$records->current()->toArray()); \$records->next(); } return \${$property}s; } /** * Persists the value of the entity in the data source */ public function save({$name} \${$property}) { if (\${$property}->getId()) { return \$this->getDao()->update( \${$property}->toArray(), 'id=' . (int)\${$property}->getId() ); } return \$this->getDao()->insert(\${$property}->toArray()); } /** * Deletes the entity from the data source */ public function delete({$name} \${$property}) { return \$this->getDao()->delete('id=' . (int)\${$property}->getId()); } } MAPPER; }
/** * Creates the show view * * @param string $entity * @param array $fields * @return string */ protected static function createShowView($entity, $fields) { $upperFirst = new UCFirst(); $lowerFirst = new LCFirst(); $camelCaseToSpace = new CamelCaseToSeparator(); $pluralize = new Pluralize(); $entityPlural = $pluralize->filter($entity); $lowerEntity = $lowerFirst->filter($entity); $data = $rendered = ''; $fields = explode(',', $fields); foreach ($fields as $field) { $fieldAndType = explode(':', $field); list($field, $type) = count($fieldAndType) === 2 ? $fieldAndType : array($field, 'string'); $ucFirst = $upperFirst->filter($field); $field = $camelCaseToSpace->filter($ucFirst); $data .= "'get{$ucFirst}' => 'some {$field}'," . PHP_EOL . " "; $rendered .= '$this->rendered->should->haveSelector(\'p>b\', ' . 'array(\'text\' => \'' . $field . ':\')); $this->rendered->should->contain(\'some ' . $field . '\');'; } return <<<SHOWVIEW <?php namespace {$entityPlural}; use \\PHPSpec\\Context\\Zend\\View as ViewContext; class DescribeShow extends ViewContext { function before() { \$this->assign('{$lowerEntity}', \$this->stub('{$entity}', array( 'getId' => '1', {$data} ))); } function itRendersThe{$entity}() { \$this->render(); {$rendered} } } SHOWVIEW; }
/** * Creates the scaffolded show action * * @param string $entity * @return string */ protected static function _getShowActionContent($entity) { $lcFirst = new LCFirst(); $lc = $lcFirst->filter($entity); return "\${$lc}Mapper = \$this->get('Model.{$entity}Mapper');\n \$this->view->{$lc} = \${$lc}Mapper->find(\$this->_request->id);"; }
/** * Gets the content of scaffolded show view * * @param string $entity * @param array $fields * @return string */ protected static function _getShowViewContent($entity, $fields) { $upperFirst = new UCFirst(); $lowerFirst = new LCFirst(); $camelCaseToSpace = new CamelCaseToSeparator(); $camelCaseToDash = new CamelCaseToDash(); $pluralize = new Pluralize(); $lowerEntity = $lowerFirst->filter($entity); $lowerEntityPlural = $pluralize->filter($lowerEntity); $dashedEntityPlural = $camelCaseToDash->filter($lowerEntityPlural); $properties = ''; foreach ($fields as $field) { $upper = $upperFirst->filter($field); $field = $camelCaseToSpace->filter($field); $field = $upperFirst->filter($field); $properties .= " <p>\n <b>{$field}:</b>\n <?php echo \$this->escape(\$this->{$lowerEntity}->get{$upper}()) ?></h3>\n </p>" . PHP_EOL . PHP_EOL; } return "<h1>Show {$entity}</h1>\n\n{$properties}\n\n<a href=\"<?php echo \$this->baseUrl(" . "'{$dashedEntityPlural}/edit/id/' ." . " (int)\$this->{$lowerEntity}->getId()) ?>\">Edit</a> |\n<a href=\"<?php echo \$this->baseUrl(" . "'{$dashedEntityPlural}') ?>\">Back</a>"; }
/** * Renders the content of the scaffolded controller spec * * @param string $entity * @param array $fields * @param string $module * @return string */ protected static function content($entity, $fields, $module) { $pluralize = new Pluralize(); $dashIt = new CamelCaseToSeparator(); $camelize = new DashToCamelCase(); $lcFirst = new LCFirst(); $ucFirst = new UCFirst(); if ($module === null) { $module = $camelize->filter($module); $namespace = 'namespace ' . $ucFirst->filter($module) . ';' . PHP_EOL; } else { $namespace = ''; } $entityPlural = $pluralize->filter($entity); $lcFirstEntity = $lcFirst->filter($entity); $lcFirstEntityPlural = $lcFirst->filter($entityPlural); $entityPluralDashed = $dashIt->filter($entityPlural); $smallCasedDashedPlural = strtolower($entityPluralDashed); $fieldsAndValues = $rendered = ''; $fields = explode(',', $fields); foreach ($fields as $field) { $fieldAndType = explode(':', $field); list($field, $type) = count($fieldAndType) === 2 ? $fieldAndType : array($field, 'string'); $fieldType = $type === 'text' ? 'textarea' : 'input'; $fieldsAndValues .= "'{$field}' => 'some {$field}'," . PHP_EOL . " "; } $appForm = "Application_Form_{$entity}Form"; return <<<CONTROLLER <?php {$namespace} class Describe{$entityPlural}Controller extends \\PHPSpec\\Context\\Zend\\Controller { // GET index function itAssignsAll{$entityPlural}ToList() { \$mapper = \$this->stub('Application_Model_{$entity}Mapper'); \$mapper->shouldReceive('fetchAll')->andReturn(array()); \$this->inject('Application.Model.{$entity}Mapper', \$mapper); \$this->get('{$smallCasedDashedPlural}/index'); \$this->assigns('{$lcFirstEntityPlural}')->should->be(array()); } // GET show function itAssignsTheRequested{$entity}ToBeShown() { \${$lcFirstEntity} = \$this->stub('Application_Model_{$entity}'); \$mapper = \$this->stub('Application_Model_{$entity}Mapper'); \$mapper->shouldReceive('find')->andReturn(\${$lcFirstEntity}); \$this->inject('Application.Model.{$entity}Mapper', \$mapper); \$this->get('{$smallCasedDashedPlural}/show'); \$this->assigns('{$lcFirstEntity}')->should->be(\${$lcFirstEntity}); } // GET edit function itPopulatesTheEditFormWithA{$entity}() { \${$lcFirstEntity}Array = array( 'id' => 1, {$fieldsAndValues} ); \${$lcFirstEntity} = \$this->stub('Application_Model_{$entity}'); \${$lcFirstEntity}->shouldReceive('toArray') ->andReturn(\${$lcFirstEntity}Array); \$mapper = \$this->stub('Application_Model_{$entity}Mapper'); \$mapper->shouldReceive('find')->andReturn(\${$lcFirstEntity}); \$this->inject('Application.Model.{$entity}Mapper', \$mapper); \$form = \$this->stub('Application_Form_{$entity}Form'); \$form->shouldReceive('populate')->with(\${$lcFirstEntity}Array); \$this->inject('Application.Form.{$entity}Form', \$form); \$this->get('{$smallCasedDashedPlural}/edit/id/1'); \$this->assigns('id')->should->be('1'); \$this->assigns('form')->should->be(\$form); } // GET new function itDisplaysThe{$entity}Form() { \$this->get('{$smallCasedDashedPlural}/new'); \$this->assigns('form')->should->beAnInstanceOf('{$appForm}'); } // POST add function itAddsTheValid{$entity}() { \$mapper = \$this->stub('Application_Model_{$entity}Mapper'); \$mapper->shouldReceive('save')->once(); \$this->inject('Application.Model.{$entity}Mapper', \$mapper); \$form = \$this->stub('Application_Form_{$entity}Form'); \$form->shouldReceive('isValid')->andReturn(true); \$this->inject('Application.Form.{$entity}Form', \$form); \$this->post('{$smallCasedDashedPlural}/add', array( {$fieldsAndValues} )); } // POST update function itUpdatesTheValid{$entity}() { \$mapper = \$this->stub('Application_Model_{$entity}Mapper'); \$mapper->shouldReceive('save'); \$this->inject('Application.Model.{$entity}Mapper', \$mapper); \$form = \$this->stub('Application_Form_{$entity}Form'); \$form->shouldReceive('isValid')->andReturn(true); \$this->inject('Application.Form.{$entity}Form', \$form); \$this->post('{$smallCasedDashedPlural}/update/id/1', array( {$fieldsAndValues} )); } // GET delete function itDeletesThe{$entity}() { \$mapper = \$this->stub('Application_Model_{$entity}Mapper'); \$mapper->shouldReceive('delete'); \$this->inject('Application.Model.{$entity}Mapper', \$mapper); \$this->get('{$smallCasedDashedPlural}/delete/id/1'); \$this->response->should->redirectTo('/{$lcFirstEntityPlural}'); } // this is because we are using the registry as container // not needed with a proper non-static IoC container function after() { \$this->clearContainer(); } } CONTROLLER; }
/** * Creates a toArray() generator * * @param array $fields * @return Zend_CodeGenerator_Php_Method */ protected function _generateToArray(array $fields) { $camelCase = new UnderscoreToCamelCase(); $body = 'return array(' . PHP_EOL; foreach ($fields as $field) { $varAndType = explode(':', $field); list($varname, $type) = count($varAndType) > 1 ? $varAndType : array($varAndType[0], 'mixed'); $key = $varname; $body .= ' \'' . $varname . '\' => $this->_' . LCFirst::apply($camelCase->filter($varname)) . ',' . PHP_EOL; } if (!empty($fields)) { $body = substr($body, 0, strlen($body) - 2) . PHP_EOL; } $body .= ');'; return new Zend_CodeGenerator_Php_Method(array('name' => "toArray", 'body' => $body, 'docblock' => "Returns the model serialized as an array" . PHP_EOL . PHP_EOL . "@return array")); }