public function initGenericClassWithOptions(TemplateClassFile $templateClassFile, array $options = array())
 {
     if (isset($options['use'])) {
         foreach ($options['use'] as $use) {
             $templateClassFile->useClass($use);
         }
     }
     if (isset($options['extends'])) {
         $templateClassFile->extendClass($options['extends']);
     }
     if (isset($options['properties'])) {
         foreach ($options['properties'] as $name => $value) {
             $templateClassFile->addProperty($name, $value);
         }
     }
     if (isset($options['constants'])) {
         foreach ($options['constants'] as $name => $value) {
             $templateClassFile->addConst($name, $value);
         }
     }
     if (isset($options['traits'])) {
         foreach ($options['traits'] as $traitClass) {
             $templateClassFile->useTrait($traitClass);
         }
     }
 }
 public function generate($actionClass, array $options = array())
 {
     if (!isset($options['namespace'])) {
         throw new RequiredConfigKeyException('action_name');
     }
     if (!isset($options['action_name'])) {
         throw new RequiredConfigKeyException('action_name');
     }
     $namespace = $options['namespace'];
     $actionName = $options['action_name'];
     $actionClass = "{$namespace}\\Action\\{$actionName}";
     $options = ['extends' => 'Action'];
     $templateClassFile = new TemplateClassFile($actionClass);
     // General use statement
     $templateClassFile->useClass('\\ActionKit\\Action');
     $templateClassFile->useClass('\\ActionKit\\RecordAction\\BaseRecordAction');
     $this->initGenericClassWithOptions($templateClassFile, $options);
     $templateClassFile->addMethod('public', 'schema', [], '');
     $templateClassFile->addMethod('public', 'run', [], 'return $this->success("Success!");');
     $code = $templateClassFile->render();
     return new GeneratedAction($actionClass, $code, $templateClassFile);
 }
 public function execute($user, $repo)
 {
     $ns = '';
     if ($appNs = $this->options->ns) {
         $ns = rtrim(str_replace(':', '\\', $appNs), '\\') . '\\';
     } elseif ($appNs = $this->getApplication()->getCurrentAppNamespace()) {
         $ns = $appNs . '\\Topic\\';
     } else {
         $this->logger->notice('Namespace is defined.');
     }
     // Use git to clone the wiki
     $wikiGitURI = "https://github.com/{$user}/{$repo}.wiki.git";
     $wikiBaseUrl = "https://github.com/{$user}/{$repo}/wiki";
     $localRepoPath = "tmp/{$repo}.wiki";
     $currentDir = getcwd();
     if (is_dir($localRepoPath)) {
         if ($this->options->update) {
             $this->logger->info("Fetching {$wikiGitURI}...");
             system("git -C {$localRepoPath} pull origin", $retval);
             if ($retval != 0) {
                 return $this->logger->error("Can't clone wiki repository");
             }
         }
     } else {
         $dirname = dirname($localRepoPath);
         if (!file_exists($dirname)) {
             mkdir($dirname, 0755, true);
         }
         $this->logger->info("Cloning {$wikiGitURI}...");
         system("git clone {$wikiGitURI} {$localRepoPath}", $retval);
         if ($retval != 0) {
             return $this->logger->error("Can't clone wiki repository");
         }
     }
     // Build classes
     $this->logger->info('Building topic classes from GitHub pages...');
     $outputDir = $this->options->dir ?: '.';
     $directory = new RecursiveDirectoryIterator($localRepoPath);
     $iterator = new RecursiveIteratorIterator($directory);
     $topics = array();
     foreach ($iterator as $file) {
         if (preg_match('/\\.git/', $file->getPathName())) {
             continue;
         }
         if (preg_match('/\\.md$/', $file->getPathName())) {
             $topicRemoteUrl = $wikiBaseUrl . '/' . $file->getFileName();
             // Used from command-line, to invoke the topic
             // $topicId = strtolower(preg_replace(array('/.md$/'),array(''),$file->getFileName()));
             // The readable topic title
             // TODO: Support non-ascii characters
             $entryName = preg_replace('/.md$/', '', $file->getFileName());
             $entryNameNonEnChars = trim(preg_replace('/[^a-zA-Z0-9-\\s]/', '', $entryName));
             $topicClassName = implode('', array_map('ucfirst', explode('-', str_replace(' ', '', $entryNameNonEnChars)))) . 'Topic';
             $topicId = strtolower(preg_replace('/\\s+/', '-', $entryNameNonEnChars));
             $topicTitle = preg_replace('/-/', ' ', $entryName);
             $topicFullClassName = $ns . $topicClassName;
             $topics[$topicId] = $topicFullClassName;
             $classFile = $outputDir . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $topicFullClassName) . '.php';
             $cTemplate = new TemplateClassFile($topicFullClassName, array('template' => 'Class.php.twig'));
             $cTemplate->addProperty('id', $topicId);
             $cTemplate->addProperty('url', $topicRemoteUrl);
             $cTemplate->addProperty('title', $topicTitle);
             $cTemplate->extendClass('\\CLIFramework\\Topic\\GitHubTopic');
             $cTemplate->addMethod('public', 'getRemoteUrl', array(), 'return $this->remoteUrl;');
             $cTemplate->addMethod('public', 'getId', array(), 'return $this->id;');
             $content = file_get_contents($file);
             $cTemplate->addMethod('public', 'getContent', array(), 'return ' . var_export($content, true) . ';', array(), false);
             $classDir = dirname($classFile);
             if (!file_exists($classDir)) {
                 mkdir($classDir, 0755, true);
             }
             $this->logger->info("Creating {$classFile}");
             if (false === file_put_contents($classFile, $cTemplate->render())) {
                 throw new Exception("Can't write file {$classFile}.");
             }
         }
     }
     $this->logger->info(wordwrap("You may now copy the below content to the 'init' method in your application class:"));
     $this->logger->writeln('-------');
     $block = new Block();
     $block->appendLine('$this->topics(' . var_export($topics, true) . ');');
     $this->logger->write($block->render());
     $this->logger->writeln('-------');
     chdir($currentDir);
     $this->logger->info('Done');
 }
 public static function create(DeclareSchema $schema)
 {
     $schemaProxyClass = $schema->getSchemaProxyClass();
     $cTemplate = new TemplateClassFile($schemaProxyClass, array('template_dirs' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'Templates', 'template' => 'Schema.php.twig'));
     $schemaClass = get_class($schema);
     $schemaArray = $schema->export();
     $cTemplate->addConst('schema_class', $schemaClass);
     $cTemplate->addConst('collection_class', $schemaArray['collection_class']);
     $cTemplate->addConst('model_class', $schemaArray['model_class']);
     $cTemplate->addConst('model_name', $schema->getModelName());
     $cTemplate->addConst('model_namespace', $schema->getNamespace());
     $cTemplate->addConst('primary_key', $schemaArray['primary_key']);
     $cTemplate->addConst('table', $schema->getTable());
     $cTemplate->addConst('label', $schema->getLabel());
     // export column names excluding virtual columns
     $cTemplate->addStaticVar('column_names', $schema->getColumnNames());
     $cTemplate->addStaticVar('column_hash', array_fill_keys($schema->getColumnNames(), 1));
     $cTemplate->addStaticVar('mixin_classes', array_reverse($schema->getMixinSchemaClasses()));
     // export column names including virutal columns
     $cTemplate->addStaticVar('column_names_include_virtual', $schema->getColumnNames(true));
     $cTemplate->schema = $schema;
     $cTemplate->schema_data = $schemaArray;
     $cTemplate->now = new DateTime();
     // Aggregate basic translations from labels
     $msgIds = $schema->getMsgIds();
     $cTemplate->setMsgIds($msgIds);
     return $cTemplate;
 }