예제 #1
0
 public function testBad_file()
 {
     // <file> vs file>
     $this->file = tempnam(sys_get_temp_dir(), 'infoxml-');
     file_put_contents($this->file, "<extension key='test.foo' type='module'>file>foo</file></extension>");
     $exc = NULL;
     try {
         $info = CRM_Extension_Info::loadFromFile($this->file);
     } catch (CRM_Extension_Exception $e) {
         $exc = $e;
     }
     $this->assertTrue(is_object($exc));
 }
예제 #2
0
 /**
  * @param $dir
  * @return null
  * @throws \CRM_Extension_Exception_ParseException
  */
 protected function whoAmI($dir)
 {
     while ($dir && dirname($dir) !== $dir && !file_exists("{$dir}/info.xml")) {
         $dir = dirname($dir);
     }
     if (file_exists("{$dir}/info.xml")) {
         $info = \CRM_Extension_Info::loadFromFile("{$dir}/info.xml");
         $name = $info->key;
         return $name;
     }
     return $name;
 }
예제 #3
0
 /**
  * Install or upgrade the code for an extension -- and perform any
  * necessary database changes (eg replacing extension metadata).
  *
  * This only works if the extension is stored in the default container.
  *
  * @param string $tmpCodeDir
  *   Path to a local directory containing a copy of the new (inert) code.
  * @throws CRM_Extension_Exception
  */
 public function replace($tmpCodeDir)
 {
     if (!$this->defaultContainer) {
         throw new CRM_Extension_Exception("Default extension container is not configured");
     }
     $newInfo = CRM_Extension_Info::loadFromFile($tmpCodeDir . DIRECTORY_SEPARATOR . CRM_Extension_Info::FILENAME);
     $oldStatus = $this->getStatus($newInfo->key);
     // find $tgtPath, $oldInfo, $typeManager
     switch ($oldStatus) {
         case self::STATUS_UNINSTALLED:
         case self::STATUS_INSTALLED:
         case self::STATUS_DISABLED:
             // There is an old copy of the extension. Try to install in the same place -- but it must go somewhere in the default-container
             list($oldInfo, $typeManager) = $this->_getInfoTypeHandler($newInfo->key);
             // throws Exception
             $tgtPath = $this->fullContainer->getPath($newInfo->key);
             if (!CRM_Utils_File::isChildPath($this->defaultContainer->getBaseDir(), $tgtPath)) {
                 // force installation in the default-container
                 $oldPath = $tgtPath;
                 $tgtPath = $this->defaultContainer->getBaseDir() . DIRECTORY_SEPARATOR . $newInfo->key;
                 CRM_Core_Session::setStatus(ts('A copy of the extension (%1) is in a system folder (%2). The system copy will be preserved, but the new copy will be used.', array(1 => $newInfo->key, 2 => $oldPath)));
             }
             break;
         case self::STATUS_INSTALLED_MISSING:
         case self::STATUS_DISABLED_MISSING:
             // the extension does not exist in any container; we're free to put it anywhere
             $tgtPath = $this->defaultContainer->getBaseDir() . DIRECTORY_SEPARATOR . $newInfo->key;
             list($oldInfo, $typeManager) = $this->_getMissingInfoTypeHandler($newInfo->key);
             // throws Exception
             break;
         case self::STATUS_UNKNOWN:
             // the extension does not exist in any container; we're free to put it anywhere
             $tgtPath = $this->defaultContainer->getBaseDir() . DIRECTORY_SEPARATOR . $newInfo->key;
             $oldInfo = $typeManager = NULL;
             break;
         default:
             throw new CRM_Extension_Exception("Cannot install or enable extension: {$newInfo->key}");
     }
     // move the code!
     switch ($oldStatus) {
         case self::STATUS_UNINSTALLED:
         case self::STATUS_UNKNOWN:
             // There are no DB records to worry about, so we'll just put the files in place
             if (!CRM_Utils_File::replaceDir($tmpCodeDir, $tgtPath)) {
                 throw new CRM_Extension_Exception("Failed to move {$tmpCodeDir} to {$tgtPath}");
             }
             break;
         case self::STATUS_INSTALLED:
         case self::STATUS_INSTALLED_MISSING:
         case self::STATUS_DISABLED:
         case self::STATUS_DISABLED_MISSING:
             // There are DB records; coordinate the file placement with the DB updates
             $typeManager->onPreReplace($oldInfo, $newInfo);
             if (!CRM_Utils_File::replaceDir($tmpCodeDir, $tgtPath)) {
                 throw new CRM_Extension_Exception("Failed to move {$tmpCodeDir} to {$tgtPath}");
             }
             $this->_updateExtensionEntry($newInfo);
             $typeManager->onPostReplace($oldInfo, $newInfo);
             break;
         default:
             throw new CRM_Extension_Exception("Cannot install or enable extension: {$newInfo->key}");
     }
     $this->refresh();
     CRM_Core_Invoke::rebuildMenuAndCaches(TRUE);
 }
예제 #4
0
 /**
  * Scan $basedir for a list of extension-keys
  *
  * @return array
  *   ($key => $relPath)
  */
 protected function getRelPaths()
 {
     if (!is_array($this->relPaths)) {
         if ($this->cache) {
             $this->relPaths = $this->cache->get($this->cacheKey);
         }
         if (!is_array($this->relPaths)) {
             $this->relPaths = array();
             $infoPaths = CRM_Utils_File::findFiles($this->baseDir, 'info.xml');
             foreach ($infoPaths as $infoPath) {
                 $relPath = CRM_Utils_File::relativize(dirname($infoPath), $this->baseDir);
                 try {
                     $info = CRM_Extension_Info::loadFromFile($infoPath);
                 } catch (CRM_Extension_Exception_ParseException $e) {
                     CRM_Core_Session::setStatus(ts('Parse error in extension: %1', array(1 => $e->getMessage())), '', 'error');
                     CRM_Core_Error::debug_log_message("Parse error in extension: " . $e->getMessage());
                     continue;
                 }
                 $this->relPaths[$info->key] = $relPath;
             }
             if ($this->cache) {
                 $this->cache->set($this->cacheKey, $this->relPaths);
             }
         }
     }
     return $this->relPaths;
 }
예제 #5
0
파일: Mapper.php 프로젝트: kidaa30/yes
 /**
  * @param string $key
  *   Extension fully-qualified-name.
  * @param bool $fresh
  *
  * @throws CRM_Extension_Exception
  * @throws Exception
  * @return CRM_Extension_Info
  */
 public function keyToInfo($key, $fresh = FALSE)
 {
     if ($fresh || !array_key_exists($key, $this->infos)) {
         try {
             $this->infos[$key] = CRM_Extension_Info::loadFromFile($this->container->getPath($key) . DIRECTORY_SEPARATOR . CRM_Extension_Info::FILENAME);
         } catch (CRM_Extension_Exception $e) {
             // file has more detailed info, but we'll fallback to DB if it's missing -- DB has enough info to uninstall
             $this->infos[$key] = CRM_Extension_System::singleton()->getManager()->createInfoFromDB($key);
             if (!$this->infos[$key]) {
                 throw $e;
             }
         }
     }
     return $this->infos[$key];
 }
예제 #6
0
 /**
  * Validate that $extractedZipPath contains valid for extension $key
  *
  * @param $key
  * @param $extractedZipPath
  *
  * @return bool
  */
 public function validateFiles($key, $extractedZipPath)
 {
     $filename = $extractedZipPath . DIRECTORY_SEPARATOR . CRM_Extension_Info::FILENAME;
     if (!is_readable($filename)) {
         CRM_Core_Session::setStatus(ts('Failed reading data from %1 during installation', array(1 => $filename)), ts('Installation Error'), 'error');
         return FALSE;
     }
     try {
         $newInfo = CRM_Extension_Info::loadFromFile($filename);
     } catch (Exception $e) {
         CRM_Core_Session::setStatus(ts('Failed reading data from %1 during installation', array(1 => $filename)), ts('Installation Error'), 'error');
         return FALSE;
     }
     if ($newInfo->key != $key) {
         CRM_Core_Error::fatal('Cannot install - there are differences between extdir XML file and archive XML file!');
     }
     return TRUE;
 }