protected function execute(InputInterface $input, OutputInterface $output) { // TODO validate that hook_civicrm_upgrade has been implemented $ctx = array(); $ctx['type'] = 'module'; $ctx['basedir'] = rtrim(getcwd(), '/'); $basedir = new Path($ctx['basedir']); $info = new Info($basedir->string('info.xml')); $info->load($ctx); $attrs = $info->get()->attributes(); if ($attrs['type'] != 'module') { $output->writeln('<error>Wrong extension type: ' . $attrs['type'] . '</error>'); return; } $dirs = new Dirs(array($basedir->string('sql'), $basedir->string($ctx['namespace']), $basedir->string($ctx['namespace'], 'Upgrader'))); $dirs->save($ctx, $output); $phpFile = $basedir->string($ctx['namespace'], 'Upgrader.php'); if (!file_exists($phpFile)) { $output->writeln(sprintf('<info>Write %s</info>', $phpFile)); file_put_contents($phpFile, $this->getContainer()->get('templating')->render('CRMCivixBundle:Code:upgrader.php.php', $ctx)); } else { $output->writeln(sprintf('<error>Skip %s: file already exists, defer to customized version</error>', $phpFile)); } $phpFile = $basedir->string($ctx['namespace'], 'Upgrader', 'Base.php'); $output->writeln(sprintf('<info>Write %s</info>', $phpFile)); file_put_contents($phpFile, $this->getContainer()->get('templating')->render('CRMCivixBundle:Code:upgrader-base.php.php', $ctx)); $module = new Module($this->getContainer()->get('templating')); $module->loadInit($ctx); $module->save($ctx, $output); }
protected function execute(InputInterface $input, OutputInterface $output) { $ctx = array(); $ctx['type'] = 'module'; $ctx['basedir'] = rtrim(getcwd(), '/'); $basedir = new Path($ctx['basedir']); $info = new Info($basedir->string('info.xml')); $info->load($ctx); $attrs = $info->get()->attributes(); if ($attrs['type'] != 'module') { $output->writeln('<error>Wrong extension type: ' . $attrs['type'] . '</error>'); return; } if (!preg_match('/^[A-Za-z0-9_]+$/', $input->getArgument('<CRM_Full_ClassName>'))) { throw new Exception("Class name must be alphanumeric (with underscores)"); } if (!preg_match('/Test$/', $input->getArgument('<CRM_Full_ClassName>'))) { throw new Exception("Class name must end with the word \"Test\""); } $ctx['testClass'] = $input->getArgument('<CRM_Full_ClassName>'); $ctx['testFile'] = strtr($ctx['testClass'], '_', '/') . '.php'; $ctx['testPath'] = $basedir->string('tests', 'phpunit', $ctx['testFile']); $dirs = new Dirs(array(dirname($ctx['testPath']))); $dirs->save($ctx, $output); if (!file_exists($ctx['testPath'])) { $output->writeln(sprintf('<info>Write %s</info>', $ctx['testPath'])); file_put_contents($ctx['testPath'], $this->getContainer()->get('templating')->render('CRMCivixBundle:Code:test.php.php', $ctx)); } else { $output->writeln(sprintf('<error>Skip %s: file already exists</error>', $ctx['testPath'])); } }
protected function execute(InputInterface $input, OutputInterface $output) { if (!preg_match('/^civicrm\\//', $input->getArgument('<web/path>'))) { throw new Exception("Web path must begin with 'civicrm/'"); } if (!preg_match('/^[A-Z][A-Za-z0-9_]*$/', $input->getArgument('<ClassName>'))) { throw new Exception("Class name should be valid (alphanumeric beginning with uppercase)"); } $ctx = array(); $ctx['type'] = 'module'; $ctx['basedir'] = rtrim(getcwd(), '/'); $ctx['shortClassName'] = $input->getArgument('<ClassName>'); $basedir = new Path($ctx['basedir']); $info = new Info($basedir->string('info.xml')); $info->load($ctx); $attrs = $info->get()->attributes(); if ($attrs['type'] != 'module') { $output->writeln('<error>Wrong extension type: ' . $attrs['type'] . '</error>'); return; } $ctx['fullClassName'] = $this->createClassName($input, $ctx); $phpFile = $basedir->string(str_replace('_', '/', $ctx['fullClassName']) . '.php'); $tplFile = $basedir->string('templates', $this->createTplName($input, $ctx)); if (preg_match('/^CRM_/', $input->getArgument('<ClassName>'))) { throw new Exception("Class name looks suspicious. Please note the final class would be \"{$ctx['fullClassName']}\""); } $dirs = new Dirs(array($basedir->string('xml', 'Menu'), dirname($phpFile), dirname($tplFile))); $dirs->save($ctx, $output); $menu = new Menu($basedir->string('xml', 'Menu', $ctx['mainFile'] . '.xml')); $menu->loadInit($ctx); if (!$menu->hasPath($input->getArgument('<web/path>'))) { $menu->addItem($ctx, $input->getArgument('<ClassName>'), $ctx['fullClassName'], $input->getArgument('<web/path>')); $menu->save($ctx, $output); } else { $output->writeln(sprintf('<error>Failed to bind %s to class %s; %s is already bound</error>', $input->getArgument('<web/path>'), $input->getArgument('<ClassName>'), $input->getArgument('<web/path>'))); } if (!file_exists($phpFile)) { $output->writeln(sprintf('<info>Write %s</info>', $phpFile)); file_put_contents($phpFile, $this->getContainer()->get('templating')->render($this->getPhpTemplate($input), $ctx)); } else { $output->writeln(sprintf('<error>Skip %s: file already exists</error>', $phpFile)); } if (!file_exists($tplFile)) { $output->writeln(sprintf('<info>Write %s</info>', $tplFile)); file_put_contents($tplFile, $this->getContainer()->get('templating')->render($this->getTplTemplate($input), $ctx)); } else { $output->writeln(sprintf('<error>Skip %s: file already exists</error>', $tplFile)); } $module = new Module($this->getContainer()->get('templating')); $module->loadInit($ctx); $module->save($ctx, $output); }
protected function execute(InputInterface $input, OutputInterface $output) { // load Civi to get access to civicrm_api_get_function_name $civicrm_api3 = $this->getContainer()->get('civicrm_api3'); if (!$civicrm_api3 || !$civicrm_api3->local) { $output->writeln("Requires access to local CiviCRM source tree. Configure civicrm_api3_conf_path.</error>"); return; } if (!preg_match('/^[A-Z][A-Za-z0-9_ \\.\\-]*$/', $input->getArgument('<Label>'))) { throw new Exception("Label should be valid"); } if (!$input->getArgument('<Name>')) { // $input->setArgument('<Name>', \CRM_Utils_String::munge(ucwords(str_replace('_', ' ', $input->getArgument('<Label>'))), '', 0)); $input->setArgument('<Name>', \CRM_Case_XMLProcessor::mungeCasetype($input->getArgument('<Label>'))); } if (!preg_match('/^[A-Z][A-Za-z0-9]*$/', $input->getArgument('<Name>'))) { throw new Exception("Name should be valid (alphanumeric beginning with uppercase)"); } $ctx = array(); $ctx['type'] = 'module'; $ctx['basedir'] = rtrim(getcwd(), '/'); $ctx['caseTypeLabel'] = $input->getArgument('<Label>'); $ctx['caseTypeName'] = $input->getArgument('<Name>'); $basedir = new Path($ctx['basedir']); $info = new Info($basedir->string('info.xml')); $info->load($ctx); $attrs = $info->get()->attributes(); if ($attrs['type'] != 'module') { $output->writeln('<error>Wrong extension type: ' . $attrs['type'] . '</error>'); return; } $dirs = new Dirs(array($basedir->string('xml', 'case'))); $dirs->save($ctx, $output); $xmlFile = $basedir->string('xml', 'case', $ctx['caseTypeName'] . '.xml'); if (!file_exists($xmlFile)) { $output->writeln(sprintf('<info>Write %s</info>', $xmlFile)); file_put_contents($xmlFile, $this->getContainer()->get('templating')->render('CRMCivixBundle:Code:case-type.xml.php', $ctx)); } else { $output->writeln(sprintf('<error>Skip %s: file already exists</error>', $xmlFile)); } $module = new Module($this->getContainer()->get('templating')); $module->loadInit($ctx); $module->save($ctx, $output); }
protected function execute(InputInterface $input, OutputInterface $output) { // load Civi to get access to civicrm_api_get_function_name $civicrm_api3 = $this->getContainer()->get('civicrm_api3'); if (!$civicrm_api3 || !$civicrm_api3->local) { $output->writeln("<error>generate:custom-xml requires access to local CiviCRM instance. Configure civicrm_api3_conf_path.</error>"); return; } $ctx = array(); $ctx['type'] = 'module'; $ctx['basedir'] = rtrim(getcwd(), '/'); $basedir = new Path($ctx['basedir']); $info = new Info($basedir->string('info.xml')); $info->load($ctx); $attrs = $info->get()->attributes(); if ($attrs['type'] != 'module') { $output->writeln('<error>Wrong extension type: ' . $attrs['type'] . '</error>'); return; } $dirs = new Dirs(array($basedir->string('xml'))); $dirs->save($ctx, $output); if ($input->getArgument('<CustomDataFile.xml>')) { $customDataXMLFile = $basedir->string($input->getArgument('<CustomDataFile.xml>')); } else { $customDataXMLFile = $basedir->string('xml', 'auto_install.xml'); } if (!$input->getOption('data') && !$input->getOption('uf')) { $output->writeln("<error>generate:custom-xml requires --data and/or --uf</error>"); return; } $customDataXML = new CustomDataXML($input->getOption('data') ? explode(',', $input->getOption('data')) : array(), $input->getOption('uf') ? explode(',', $input->getOption('uf')) : array(), $customDataXMLFile, $input->getOption('force')); $customDataXML->save($ctx, $output); if (preg_match('/\\/xml\\/.*_install.xml$/', $customDataXMLFile)) { $output->writeln(" * NOTE: This filename ends with \"_install.xml\". If you would like to load it automatically on new sites, then make sure there is an install/upgrade class (i.e. run \"civix generate:upgrader\")"); } else { $output->writeln(" * NOTE: By default, this file will not be loaded automatically -- you must define installation or upgrade logic to load the file."); } }
protected function execute(InputInterface $input, OutputInterface $output) { // load Civi to get access to civicrm_api_get_function_name $civicrm_api3 = $this->getContainer()->get('civicrm_api3'); if (!$civicrm_api3 || !$civicrm_api3->local) { $output->writeln("<error>--copy requires access to local CiviCRM source tree. Configure civicrm_api3_conf_path.</error>"); return; } $ctx = array(); $ctx['type'] = 'module'; $ctx['basedir'] = rtrim(getcwd(), '/'); $basedir = new Path($ctx['basedir']); $info = new Info($basedir->string('info.xml')); $info->load($ctx); $attrs = $info->get()->attributes(); if ($attrs['type'] != 'module') { $output->writeln('<error>Wrong extension type: ' . $attrs['type'] . '</error>'); return; } if (!preg_match('/^[A-Za-z0-9]+$/', $input->getArgument('<EntityName>'))) { throw new Exception("Entity name must be alphanumeric camel-case"); } if (!preg_match('/^[A-Za-z0-9]+$/', $input->getArgument('<ActionName>'))) { throw new Exception("Action name must be alphanumeric camel-case"); } if ($input->getOption('schedule') && !in_array($input->getOption('schedule'), self::getSchedules())) { throw new Exception("Schedule must be one of: " . implode(', ', self::getSchedules())); } $ctx['entityNameCamel'] = ucfirst($input->getArgument('<EntityName>')); $ctx['actionNameCamel'] = ucfirst($input->getArgument('<ActionName>')); if (function_exists('civicrm_api_get_function_name')) { $ctx['apiFunction'] = strtolower(civicrm_api_get_function_name($ctx['entityNameCamel'], $ctx['actionNameCamel'], self::API_VERSION)); } elseif (function_exists('_civicrm_api_get_entity_name_from_camel')) { $ctx['apiFunction'] = 'civicrm_api' . self::API_VERSION . '_' . _civicrm_api_get_entity_name_from_camel($ctx['entityNameCamel']) . '_' . $ctx['actionNameCamel']; } else { throw new Exception("Failed to determine proper API function name. Perhaps the API internals have changed?"); } $ctx['apiFile'] = $basedir->string('api', 'v3', $ctx['entityNameCamel'], $ctx['actionNameCamel'] . '.php'); $ctx['apiCronFile'] = $basedir->string('api', 'v3', $ctx['entityNameCamel'], $ctx['actionNameCamel'] . '.mgd.php'); $dirs = new Dirs(array(dirname($ctx['apiFile']))); $dirs->save($ctx, $output); if (!file_exists($ctx['apiFile'])) { $output->writeln(sprintf('<info>Write %s</info>', $ctx['apiFile'])); file_put_contents($ctx['apiFile'], $this->getContainer()->get('templating')->render('CRMCivixBundle:Code:api.php.php', $ctx)); } else { $output->writeln(sprintf('<error>Skip %s: file already exists</error>', $ctx['apiFile'])); } if ($input->getOption('schedule')) { if (!file_exists($ctx['apiCronFile'])) { $mgdEntities = array(array('name' => 'Cron:' . $ctx['entityNameCamel'] . '.' . $ctx['actionNameCamel'], 'entity' => 'Job', 'params' => array('version' => 3, 'name' => sprintf('Call %s.%s API', $ctx['entityNameCamel'], $ctx['actionNameCamel']), 'description' => sprintf('Call %s.%s API', $ctx['entityNameCamel'], $ctx['actionNameCamel']), 'run_frequency' => $input->getOption('schedule'), 'api_entity' => $ctx['entityNameCamel'], 'api_action' => $ctx['actionNameCamel'], 'parameters' => ''))); $header = "// This file declares a managed database record of type \"Job\".\n" . "// The record will be automatically inserted, updated, or deleted from the\n" . "// database as appropriate. For more details, see \"hook_civicrm_managed\" at:\n" . "// http://wiki.civicrm.org/confluence/display/CRMDOC42/Hook+Reference"; $mgdBuilder = new PhpData($ctx['apiCronFile'], $header); $mgdBuilder->set($mgdEntities); $mgdBuilder->save($ctx, $output); } else { $output->writeln(sprintf('<error>Skip %s: file already exists</error>', $ctx['apiCronFile'])); } } $module = new Module($this->getContainer()->get('templating')); $module->loadInit($ctx); $module->save($ctx, $output); }