Beispiel #1
0
 /**
  * Initializes the console app by creating the command runner.
  *
  * @return null
  */
 public function init()
 {
     // Set default timezone to UTC
     date_default_timezone_set('UTC');
     // Import all the built-in components
     foreach ($this->componentAliases as $alias) {
         Craft::import($alias);
     }
     // Attach our Craft app behavior.
     $this->attachBehavior('AppBehavior', new AppBehavior());
     // Initialize Cache and LogRouter right away (order is important)
     $this->getComponent('cache');
     $this->getComponent('log');
     // So we can try to translate Yii framework strings
     $this->coreMessages->attachEventHandler('onMissingTranslation', array('Craft\\LocalizationHelper', 'findMissingTranslation'));
     // Set our own custom runtime path.
     $this->setRuntimePath(craft()->path->getRuntimePath());
     // Attach our own custom Logger
     Craft::setLogger(new Logger());
     // No need for these.
     craft()->log->removeRoute('WebLogRoute');
     craft()->log->removeRoute('ProfileLogRoute');
     // Load the plugins
     craft()->plugins->loadPlugins();
     // Validate some basics on the database configuration file.
     craft()->validateDbConfigFile();
     // Call parent::init before the plugin console command logic so craft()->commandRunner will be available to us.
     parent::init();
     foreach (craft()->plugins->getPlugins() as $plugin) {
         $commandsPath = craft()->path->getPluginsPath() . StringHelper::toLowerCase($plugin->getClassHandle()) . '/consolecommands/';
         if (IOHelper::folderExists($commandsPath)) {
             craft()->commandRunner->addCommands(rtrim($commandsPath, '/'));
         }
     }
 }
 /**
  * Make handle from source name.
  *
  * @param $name
  *
  * @return string
  */
 private function _makeHandle($name, $sourceId)
 {
     // Remove HTML tags
     $handle = preg_replace('/<(.*?)>/', '', $name);
     $handle = preg_replace('/<[\'"‘’“”\\[\\]\\(\\)\\{\\}:]>/', '', $handle);
     $handle = StringHelper::toLowerCase($handle);
     $handle = StringHelper::asciiString($handle);
     $handle = preg_replace('/^[^a-z]+/', '', $handle);
     // In case it was an all non-ASCII handle, have a default.
     if (!$handle) {
         $handle = 'source' . $sourceId;
     }
     $handleParts = preg_split('/[^a-z0-9]+/', $handle);
     $handle = '';
     foreach ($handleParts as $index => &$part) {
         if ($index) {
             $part = ucfirst($part);
         }
         $handle .= $part;
     }
     $appendix = '';
     while (true) {
         $taken = craft()->db->createCommand()->select('handle')->from('assetsources')->where('handle = :handle', array(':handle' => $handle . $appendix))->queryScalar();
         if ($taken) {
             $appendix = (int) $appendix + 1;
         } else {
             break;
         }
     }
     return $handle . $appendix;
 }
 public function counter($requestData)
 {
     $period = isset($requestData['period']) ? $requestData['period'] : null;
     $dimension = isset($requestData['options']['dimension']) ? $requestData['options']['dimension'] : null;
     $metric = isset($requestData['options']['metric']) ? $requestData['options']['metric'] : null;
     $start = date('Y-m-d', strtotime('-1 ' . $period));
     $end = date('Y-m-d');
     // Counter
     $criteria = new Analytics_RequestCriteriaModel();
     $criteria->startDate = $start;
     $criteria->endDate = $end;
     $criteria->metrics = $metric;
     if ($dimension) {
         $optParams = array('filters' => $dimension . '!=(not set);' . $dimension . '!=(not provided)');
         $criteria->optParams = $optParams;
     }
     $response = craft()->analytics->sendRequest($criteria);
     if (!empty($response['rows'][0][0]['f'])) {
         $count = $response['rows'][0][0]['f'];
     } else {
         $count = 0;
     }
     $counter = array('count' => $count, 'label' => StringHelper::toLowerCase(Craft::t(craft()->analytics_metadata->getDimMet($metric))));
     // Return JSON
     return ['type' => 'counter', 'counter' => $counter, 'response' => $response, 'metric' => Craft::t(craft()->analytics_metadata->getDimMet($metric)), 'period' => $period, 'periodLabel' => Craft::t('this ' . $period)];
 }
Beispiel #4
0
 /**
  * Saves log messages in files.
  *
  * @param array $logs The list of log messages
  *
  * @return null
  */
 protected function processLogs($logs)
 {
     $types = array();
     foreach ($logs as $log) {
         $message = LoggingHelper::redact($log[0]);
         $level = $log[1];
         $category = $log[2];
         $time = $log[3];
         $force = isset($log[4]) && $log[4] == true ? true : false;
         $plugin = isset($log[5]) ? StringHelper::toLowerCase($log[5]) : 'craft';
         if (isset($types[$plugin])) {
             $types[$plugin] .= $this->formatLogMessageWithForce($message, $level, $category, $time, $force, $plugin);
         } else {
             $types[$plugin] = $this->formatLogMessageWithForce($message, $level, $category, $time, $force, $plugin);
         }
     }
     foreach ($types as $plugin => $text) {
         $text .= PHP_EOL . '******************************************************************************************************' . PHP_EOL;
         $this->setLogFile($plugin . '.log');
         $logFile = IOHelper::normalizePathSeparators($this->getLogPath() . '/' . $this->getLogFile());
         // Check the config setting first.  Is it set to true?
         if (craft()->config->get('useWriteFileLock') === true) {
             $lock = true;
         } else {
             if (craft()->config->get('useWriteFileLock') === false) {
                 $lock = false;
             } else {
                 if (craft()->cache->get('useWriteFileLock') === 'yes') {
                     $lock = true;
                 } else {
                     $lock = false;
                 }
             }
         }
         $fp = @fopen($logFile, 'a');
         if ($lock) {
             @flock($fp, LOCK_EX);
         }
         if (IOHelper::getFileSize($logFile) > $this->getMaxFileSize() * 1024) {
             $this->rotateFiles();
             if ($lock) {
                 @flock($fp, LOCK_UN);
             }
             @fclose($fp);
             if ($lock) {
                 IOHelper::writeToFile($logFile, $text, false, true, false);
             } else {
                 IOHelper::writeToFile($logFile, $text, false, true, true);
             }
         } else {
             @fwrite($fp, $text);
             if ($lock) {
                 @flock($fp, LOCK_UN);
             }
             @fclose($fp);
         }
     }
 }
Beispiel #5
0
 /**
  * Checks to see if the given name is valid in the enum.
  *
  * @param      $name   The name to search for.
  * @param bool $strict Defaults to false. If set to true, will do a case sensitive search for the name.
  *
  * @return bool true if it is a valid name, false otherwise.
  */
 public static function isValidName($name, $strict = false)
 {
     $constants = static::_getConstants();
     if ($strict) {
         return array_key_exists($name, $constants);
     }
     $keys = array_map(array('Craft\\StringHelper', 'toLowerCase'), array_keys($constants));
     return in_array(StringHelper::toLowerCase($name), $keys);
 }
Beispiel #6
0
 /**
  * A wrapper for writing to the log files for plugins that will ultimately call {@link Craft::log()}. This allows
  * plugins to be able to write to their own log files at `craft/storage/runtime/logs/pluginHandle.log` using
  * `PluginHandle::log()` syntax.
  *
  * @param        $msg   The message to be logged.
  * @param string $level The level of the message (e.g. LogLevel::Trace', LogLevel::Info, LogLevel::Warning or
  *                      LogLevel::Error).
  * @param bool   $force Whether to force the message to be logged regardless of the level or category.
  *
  * @return mixed
  */
 public static function log($msg, $level = LogLevel::Info, $force = false)
 {
     $plugin = get_called_class();
     // Chunk off any namespaces
     $parts = explode('\\', $plugin);
     if (count($parts) > 0) {
         $plugin = $parts[count($parts) - 1];
     }
     // Remove the trailing 'Plugin'.
     $plugin = str_replace('Plugin', '', $plugin);
     Craft::log($msg, $level, $force, 'plugin', StringHelper::toLowerCase($plugin));
 }
 /**
  * @param string $name
  *
  * @return mixed
  */
 public function __get($name)
 {
     $plugin = craft()->plugins->getPlugin($name);
     if ($plugin && $plugin->isEnabled) {
         $pluginName = $plugin->getClassHandle();
         $className = __NAMESPACE__ . '\\' . $pluginName . 'Variable';
         // Variables should already be imported by the plugin service, but let's double check.
         if (!class_exists($className)) {
             Craft::import('plugins.' . StringHelper::toLowerCase($pluginName) . '.variables.' . $pluginName . 'Variable');
         }
         return new $className();
     }
 }
Beispiel #8
0
 /**
  * Removes a route from the LogRouter by class name.
  *
  * @param $class
  *
  * @return null
  */
 public function removeRoute($class)
 {
     $match = false;
     for ($counter = 0; $counter < sizeof($this->_routes); $counter++) {
         if (StringHelper::toLowerCase(get_class($this->_routes[$counter])) == StringHelper::toLowerCase(__NAMESPACE__ . '\\' . $class)) {
             $match = $counter;
             break;
         }
     }
     if (is_numeric($match)) {
         array_splice($this->_routes, $match, 1);
     }
 }
 /**
  * Get the sections of the CP.
  *
  * @return array
  */
 public function nav()
 {
     $nav['dashboard'] = array('label' => Craft::t('Dashboard'));
     if (craft()->sections->getTotalEditableSections()) {
         $nav['entries'] = array('label' => Craft::t('Entries'));
     }
     $globals = craft()->globals->getEditableSets();
     if ($globals) {
         $nav['globals'] = array('label' => Craft::t('Globals'), 'url' => 'globals/' . $globals[0]->handle);
     }
     if (craft()->categories->getEditableGroupIds()) {
         $nav['categories'] = array('label' => Craft::t('Categories'));
     }
     if (craft()->assetSources->getTotalViewableSources()) {
         $nav['assets'] = array('label' => Craft::t('Assets'));
     }
     if (craft()->getEdition() == Craft::Pro && craft()->userSession->checkPermission('editUsers')) {
         $nav['users'] = array('label' => Craft::t('Users'));
     }
     // Add any Plugin nav items
     $plugins = craft()->plugins->getPlugins();
     foreach ($plugins as $plugin) {
         if ($plugin->hasCpSection()) {
             if (craft()->userSession->checkPermission('accessPlugin-' . $plugin->getClassHandle())) {
                 $lcHandle = StringHelper::toLowerCase($plugin->getClassHandle());
                 $nav[$lcHandle] = array('label' => $plugin->getName());
             }
         }
     }
     // Allow plugins to modify the nav
     craft()->plugins->call('modifyCpNav', array(&$nav));
     // Figure out which item is selected, and normalize the items
     $firstSegment = craft()->request->getSegment(1);
     if ($firstSegment == 'myaccount') {
         $firstSegment = 'users';
     }
     foreach ($nav as $handle => &$item) {
         if (is_string($item)) {
             $item = array('label' => $item);
         }
         $item['sel'] = $handle == $firstSegment;
         if (isset($item['url'])) {
             $item['url'] = UrlHelper::getUrl($item['url']);
         } else {
             $item['url'] = UrlHelper::getUrl($handle);
         }
     }
     return $nav;
 }
 /**
  * Creates a slug based on a given string.
  *
  * @param string $str
  *
  * @return string
  */
 public static function createSlug($str)
 {
     // Remove HTML tags
     $slug = preg_replace('/<(.*?)>/u', '', $str);
     // Remove inner-word punctuation.
     $slug = preg_replace('/[\'"‘’“”\\[\\]\\(\\)\\{\\}:]/u', '', $slug);
     if (craft()->config->get('allowUppercaseInSlug') === false) {
         // Make it lowercase
         $slug = StringHelper::toLowerCase($slug);
     }
     // Get the "words". Split on anything that is not alphanumeric, or a period, underscore, or hyphen.
     preg_match_all('/[\\p{L}\\p{N}\\._-]+/u', $slug, $words);
     $words = ArrayHelper::filterEmptyStringsFromArray($words[0]);
     $slug = implode(craft()->config->get('slugWordSeparator'), $words);
     return $slug;
 }
Beispiel #11
0
 /**
  * @param string $name
  *
  * @return mixed
  */
 public function __get($name)
 {
     $plugin = craft()->plugins->getPlugin($name);
     if ($plugin && $plugin->isEnabled) {
         $pluginName = $plugin->getClassHandle();
         $className = __NAMESPACE__ . '\\' . $pluginName . 'Variable';
         // Variables should already be imported by the plugin service, but let's double check.
         if (!class_exists($className)) {
             Craft::import('plugins.' . StringHelper::toLowerCase($pluginName) . '.variables.' . $pluginName . 'Variable');
         }
         // If we haven't done this one yet, create it and save it for later.
         if (!isset($this->_pluginVariableInstances[$className])) {
             $this->_pluginVariableInstances[$className] = new $className();
         }
         return $this->_pluginVariableInstances[$className];
     }
 }
 /**
  * Backup All Forms
  */
 public function backupAllForms()
 {
     $forms = FormBuilder2_FormRecord::model()->ordered()->findAll();
     $table = 'craft_formbuilder2_forms';
     if ($forms) {
         $this->_currentVersion = 'v' . craft()->getVersion() . '.' . craft()->getBuild();
         $siteName = IOHelper::cleanFilename(StringHelper::asciiString(craft()->getSiteName()));
         $fileName = ($siteName ? $siteName . '_' : '') . gmdate('ymd_His') . '_' . $this->_currentVersion . '.sql';
         $this->_filePath = craft()->path->getDbBackupPath() . StringHelper::toLowerCase($fileName);
         $this->_processHeader();
         $results = $this->_processResult($table);
         $this->_processConstraints();
         $this->_processFooter();
         $filepath = $this->_filePath;
         $this->_processFile($fileName, $filepath);
     } else {
         return false;
     }
 }
 /**
  * Triggers the database backup including all DML and DDL and writes it out to a file.
  *
  * @return string The path to the database backup file.
  */
 public function run()
 {
     // Normalize the ignored table names if there is a table prefix set.
     if (($tablePrefix = craft()->config->get('tablePrefix', ConfigFile::Db)) !== '') {
         foreach ($this->_ignoreDataTables as $key => $tableName) {
             $this->_ignoreDataTables[$key] = $tablePrefix . '_' . $tableName;
         }
     }
     $this->_currentVersion = 'v' . craft()->getVersion() . '.' . craft()->getBuild();
     $fileName = IOHelper::cleanFilename(craft()->getSiteName()) . '_' . gmdate('ymd_His') . '_' . $this->_currentVersion . '.sql';
     $this->_filePath = craft()->path->getDbBackupPath() . StringHelper::toLowerCase($fileName);
     $this->_processHeader();
     foreach (craft()->db->getSchema()->getTables() as $resultName => $val) {
         $this->_processResult($resultName);
     }
     $this->_processConstraints();
     $this->_processFooter();
     return $this->_filePath;
 }
 /**
  * @param $object
  * @param $attribute
  *
  * @return null
  */
 protected function validateAttribute($object, $attribute)
 {
     $handle = $object->{$attribute};
     // Handles are always required, so if it's blank, the required validator will catch this.
     if ($handle) {
         $reservedWords = array_merge($this->reservedWords, static::$baseReservedWords);
         $reservedWords = array_map(array('Craft\\StringHelper', 'toLowerCase'), $reservedWords);
         $lcHandle = StringHelper::toLowerCase($handle);
         if (in_array($lcHandle, $reservedWords)) {
             $message = Craft::t('“{handle}” is a reserved word.', array('handle' => $handle));
             $this->addError($object, $attribute, $message);
         } else {
             if (!preg_match('/^' . static::$handlePattern . '$/', $handle)) {
                 $altMessage = Craft::t('“{handle}” isn’t a valid handle.', array('handle' => $handle));
                 $message = $this->message !== null ? $this->message : $altMessage;
                 $this->addError($object, $attribute, $message);
             }
         }
     }
 }
 /**
  * @param string $name command name (case-insensitive)
  *
  * @return \CConsoleCommand The command object. Null if the name is invalid.
  */
 public function createCommand($name)
 {
     $name = StringHelper::toLowerCase($name);
     $command = null;
     if (isset($this->commands[$name])) {
         $command = $this->commands[$name];
     } else {
         $commands = array_change_key_case($this->commands);
         if (isset($commands[$name])) {
             $command = $commands[$name];
         }
     }
     if ($command !== null) {
         if (is_string($command)) {
             if (strpos($command, '/') !== false || strpos($command, '\\') !== false) {
                 $className = IOHelper::getFileName($command, false);
                 // If it's a default framework command, don't namespace it.
                 if (strpos($command, 'framework') === false) {
                     $className = __NAMESPACE__ . '\\' . $className;
                 }
                 if (!class_exists($className, false)) {
                     require_once $command;
                 }
             } else {
                 $className = Craft::import($command);
             }
             return new $className($name, $this);
         } else {
             return Craft::createComponent($command, $name, $this);
         }
     } else {
         if ($name === 'help') {
             return new \CHelpCommand('help', $this);
         } else {
             return null;
         }
     }
 }
 /**
  * Returns the HTML for the Target Locale setting.
  *
  * @access protected
  * @return string|null
  */
 protected function getTargetLocaleFieldHtml($elementType, $targetLocale, $elementName)
 {
     if (craft()->hasPackage(CraftPackage::Localize) && $elementType->isLocalized()) {
         $localeOptions = array(array('label' => Craft::t('Same as source'), 'value' => null));
         foreach (craft()->i18n->getSiteLocales() as $locale) {
             $localeOptions[] = array('label' => $locale->getName(), 'value' => $locale->getId());
         }
         return craft()->templates->renderMacro('_includes/forms', 'selectField', array(array('label' => Craft::t('Target Locale'), 'instructions' => Craft::t('Which locale do you want to select {type} in?', array('type' => StringHelper::toLowerCase($elementName))), 'id' => 'targetLocale', 'name' => 'targetLocale', 'options' => $localeOptions, 'value' => $targetLocale)));
     }
 }
 /**
  * Get icon path for a given extension
  *
  * @param $ext
  *
  * @return string
  */
 private function _getIconPath($ext)
 {
     $sourceIconPath = craft()->path->getResourcesPath() . 'images/file.svg';
     $extLength = mb_strlen($ext);
     if ($extLength > 5) {
         // Too long; just use the blank file icon
         return $sourceIconPath;
     }
     // See if the icon already exists
     $iconPath = craft()->path->getAssetsIconsPath() . StringHelper::toLowerCase($ext) . '.svg';
     if (IOHelper::fileExists($iconPath)) {
         return $iconPath;
     }
     // Create a new one
     $svgContents = IOHelper::getFileContents($sourceIconPath);
     $textSize = $extLength <= 3 ? '26' : ($extLength == 4 ? '22' : '18');
     $textNode = '<text x="50" y="73" text-anchor="middle" font-family="sans-serif" fill="#8F98A3" ' . 'font-size="' . $textSize . '">' . StringHelper::toUpperCase($ext) . '</text>';
     $svgContents = str_replace('<!-- EXT -->', $textNode, $svgContents);
     IOHelper::writeToFile($iconPath, $svgContents);
     return $iconPath;
 }
Beispiel #18
0
 /**
  * Returns the content table name for a given Matrix field.
  *
  * @param FieldModel $matrixField  The Matrix field.
  * @param bool       $useOldHandle Whether the method should use the field’s old handle when determining the table
  *                                 name (e.g. to get the existing table name, rather than the new one).
  *
  * @return string|false The table name, or `false` if $useOldHandle was set to `true` and there was no old handle.
  */
 public function getContentTableName(FieldModel $matrixField, $useOldHandle = false)
 {
     $name = '';
     do {
         if ($useOldHandle) {
             if (!$matrixField->oldHandle) {
                 return false;
             }
             $handle = $matrixField->oldHandle;
         } else {
             $handle = $matrixField->handle;
         }
         $name = '_' . StringHelper::toLowerCase($handle) . $name;
     } while ($matrixField = $this->getParentMatrixField($matrixField));
     return 'matrixcontent' . $name;
 }
Beispiel #19
0
 /**
  * Function that (almost) mimics Craft's inner slugify process.
  * But... we allow forward slashes to stay, so we can create full uri's.
  *
  * @param string $slug
  *
  * @return string
  */
 public function slugify($slug)
 {
     // Remove HTML tags
     $slug = preg_replace('/<(.*?)>/u', '', $slug);
     // Remove inner-word punctuation.
     $slug = preg_replace('/[\'"‘’“”\\[\\]\\(\\)\\{\\}:]/u', '', $slug);
     if (craft()->config->get('allowUppercaseInSlug') === false) {
         // Make it lowercase
         $slug = StringHelper::toLowerCase($slug);
     }
     // Get the "words".  Split on anything that is not a unicode letter or number. Periods, underscores, hyphens and forward slashes get a pass.
     preg_match_all('/[\\p{L}\\p{N}\\.\\/_-]+/u', $slug, $words);
     $words = ArrayHelper::filterEmptyStringsFromArray($words[0]);
     $slug = implode(craft()->config->get('slugWordSeparator'), $words);
     return $slug;
 }
 /**
  * Returns whether an image can have EXIF information embedded.
  *
  * @param string $filePath The path to the image
  *
  * @return bool
  */
 public static function canHaveExifData($filePath)
 {
     $extension = IOHelper::getExtension($filePath);
     return in_array(StringHelper::toLowerCase($extension), array('jpg', 'jpeg', 'tiff'));
 }
 /**
  * Used for creating a new migration, for either Craft or a plugin.
  *
  *    yiic migrate create MigrationDescription PluginHandle
  *
  * If PluginHandle is omitted, the migration is created for Craft in craft/app/migrations. If it is available, the
  * migration is created in craft/plugins/PluginHandle/migrations.
  *
  * The migration description can only contain letters, digits and/or underscore characters.
  *
  * @param array $args The arguments passed in.
  *
  * @return int
  */
 public function actionCreate($args)
 {
     $pluginHandle = false;
     if (isset($args[1])) {
         // See if this is a plugin
         $plugin = craft()->plugins->getPlugin($args[1]);
         if ($plugin) {
             $name = $args[0];
             $pluginHandle = $args[1];
         } else {
             $name = $args[1];
         }
         if (!preg_match('/^\\w+$/', $name)) {
             echo "Error: The name of the migration must contain letters, digits and/or underscore characters only.\n";
             return 1;
         }
         $fullName = 'm' . gmdate('ymd_His') . '_' . $name;
         $migrationNameDesc = 'mYYMMDD_HHMMSS_migrationName';
     } else {
         $this->usageError('Please provide a name for the new migration.');
         return 1;
     }
     if ($pluginHandle) {
         $this->_validatePlugin($pluginHandle);
         if (!preg_match('/^\\w+$/', $pluginHandle)) {
             echo "Error: The name of the plugin must contain letters, digits and/or underscore characters only.\n";
             return 1;
         }
         $fullName = 'm' . gmdate('ymd_His') . '_' . StringHelper::toLowerCase($pluginHandle) . '_' . $name;
         $migrationNameDesc = 'mYYMMDD_HHMMSS_pluginHandle_migrationName';
         // The plugin path should always be the plugin's migration directory.
         $path = craft()->path->getMigrationsPath($pluginHandle);
     } else {
         // The plugin path for Craft can vary.
         $path = rtrim(IOHelper::normalizePathSeparators($args[0]), '/') . '/';
     }
     $content = strtr(craft()->migrations->getTemplate(), array('{ClassName}' => $fullName, '{MigrationNameDesc}' => $migrationNameDesc));
     $file = $path . $fullName . '.php';
     if ($this->confirm("Create new migration '{$file}'?")) {
         IOHelper::writeToFile($file, $content);
         echo "New migration created successfully.\n";
     }
 }
 /**
  * Returns the target app language.
  *
  * @param bool Whether the user's preferred language should be used
  * @return string|null
  */
 public function getTargetLanguage($useUserLanguage = true)
 {
     if ($this->isInstalled()) {
         // Will any locale validation be necessary here?
         if ($useUserLanguage || defined('CRAFT_LOCALE')) {
             if ($useUserLanguage) {
                 $locale = 'auto';
             } else {
                 $locale = StringHelper::toLowerCase(CRAFT_LOCALE);
             }
             // Get the list of actual site locale IDs
             $siteLocaleIds = craft()->i18n->getSiteLocaleIds();
             // Is it set to "auto"?
             if ($locale == 'auto') {
                 // Prevents a PHP notice in case the session failed to start, for whatever reason.
                 if (craft()->getComponent('userSession', false)) {
                     // Place this within a try/catch in case userSession is being fussy.
                     try {
                         // If the user is logged in *and* has a primary language set, use that
                         $user = craft()->userSession->getUser();
                         if ($user && $user->preferredLocale) {
                             return $user->preferredLocale;
                         }
                     } catch (\Exception $e) {
                         Craft::log("Tried to determine the user's preferred locale, but got this exception: " . $e->getMessage(), LogLevel::Error);
                     }
                 }
                 // Is there a default CP language?
                 if ($defaultCpLanguage = craft()->config->get('defaultCpLanguage')) {
                     // Make sure it's one of the site locales
                     $defaultCpLanguage = StringHelper::toLowerCase($defaultCpLanguage);
                     if (in_array($defaultCpLanguage, $siteLocaleIds)) {
                         return $defaultCpLanguage;
                     }
                 }
                 // Otherwise check if the browser's preferred language matches any of the site locales
                 $browserLanguages = craft()->request->getBrowserLanguages();
                 if ($browserLanguages) {
                     foreach ($browserLanguages as $language) {
                         if (in_array($language, $siteLocaleIds)) {
                             return $language;
                         }
                     }
                 }
             } else {
                 if (in_array($locale, $siteLocaleIds)) {
                     return $locale;
                 }
             }
         }
         // Use the primary site locale by default
         return craft()->i18n->getPrimarySiteLocaleId();
     } else {
         return $this->_getFallbackLanguage();
     }
 }
Beispiel #23
0
 /**
  * Return a file's kind by extension.
  *
  * @param string $extension
  *
  * @return int|string
  */
 public static function getFileKind($extension)
 {
     $extension = StringHelper::toLowerCase($extension);
     $fileKinds = static::getFileKinds();
     foreach ($fileKinds as $kind => $info) {
         if (in_array($extension, $info['extensions'])) {
             return $kind;
         }
     }
     return 'unknown';
 }
 /**
  * Preps a {@link DbCommand} object for querying for elements, based on a given element criteria.
  *
  * @param ElementCriteriaModel &$criteria     The element criteria model
  * @param string               &$contentTable The content table that should be joined in. (This variable will
  *                                            actually get defined by buildElementsQuery(), and is passed by
  *                                            reference so whatever’s calling the method will have access to its
  *                                            value.)
  * @param array                &$fieldColumns Info about the content field columns being selected. (This variable
  *                                            will actually get defined by buildElementsQuery(), and is passed by
  *                                            reference so whatever’s calling the method will have access to its
  *                                            value.)
  *
  * @return DbCommand|false The DbCommand object, or `false` if the method was able to determine ahead of time that
  *                         there’s no chance any elements are going to be found with the given parameters.
  */
 public function buildElementsQuery(&$criteria = null, &$contentTable = null, &$fieldColumns = null)
 {
     if (!$criteria instanceof ElementCriteriaModel) {
         $criteria = $this->getCriteria('Entry', $criteria);
     }
     $elementType = $criteria->getElementType();
     if (!$elementType->isLocalized()) {
         // The criteria *must* be set to the primary locale
         $criteria->locale = craft()->i18n->getPrimarySiteLocaleId();
     } else {
         if (!$criteria->locale) {
             // Default to the current app locale
             $criteria->locale = craft()->language;
         }
     }
     // Set up the query
     // ---------------------------------------------------------------------
     $query = craft()->db->createCommand()->select('elements.id, elements.type, elements.enabled, elements.archived, elements.dateCreated, elements.dateUpdated, elements_i18n.slug, elements_i18n.uri, elements_i18n.enabled AS localeEnabled')->from('elements elements')->join('elements_i18n elements_i18n', 'elements_i18n.elementId = elements.id')->where('elements_i18n.locale = :locale', array(':locale' => $criteria->locale))->group('elements.id');
     if ($elementType->hasContent()) {
         $contentTable = $elementType->getContentTableForElementsQuery($criteria);
         if ($contentTable) {
             $contentCols = 'content.id AS contentId';
             if ($elementType->hasTitles()) {
                 $contentCols .= ', content.title';
             }
             // TODO: Replace this with a call to getFieldsForElementsQuery() in 3.0
             $fieldColumns = $elementType->getContentFieldColumnsForElementsQuery($criteria);
             foreach ($fieldColumns as $column) {
                 $contentCols .= ', content.' . $column['column'];
             }
             $query->addSelect($contentCols);
             $query->join($contentTable . ' content', 'content.elementId = elements.id');
             $query->andWhere('content.locale = :locale');
         }
     }
     // Basic element params
     // ---------------------------------------------------------------------
     // If the 'id' parameter is set to any empty value besides `null`, don't return anything
     if ($criteria->id !== null && empty($criteria->id)) {
         return false;
     }
     if ($criteria->id) {
         $query->andWhere(DbHelper::parseParam('elements.id', $criteria->id, $query->params));
     }
     if ($criteria->archived) {
         $query->andWhere('elements.archived = 1');
     } else {
         $query->andWhere('elements.archived = 0');
         if ($criteria->status) {
             $statusConditions = array();
             $statuses = ArrayHelper::stringToArray($criteria->status);
             foreach ($statuses as $status) {
                 $status = StringHelper::toLowerCase($status);
                 // Is this a supported status?
                 if (in_array($status, array_keys($elementType->getStatuses()))) {
                     if ($status == BaseElementModel::ENABLED) {
                         $statusConditions[] = 'elements.enabled = 1';
                     } else {
                         if ($status == BaseElementModel::DISABLED) {
                             $statusConditions[] = 'elements.enabled = 0';
                         } else {
                             $elementStatusCondition = $elementType->getElementQueryStatusCondition($query, $status);
                             if ($elementStatusCondition) {
                                 $statusConditions[] = $elementStatusCondition;
                             } else {
                                 if ($elementStatusCondition === false) {
                                     return false;
                                 }
                             }
                         }
                     }
                 }
             }
             if ($statusConditions) {
                 if (count($statusConditions) == 1) {
                     $statusCondition = $statusConditions[0];
                 } else {
                     array_unshift($statusConditions, 'or');
                     $statusCondition = $statusConditions;
                 }
                 $query->andWhere($statusCondition);
             }
         }
     }
     if ($criteria->dateCreated) {
         $query->andWhere(DbHelper::parseDateParam('elements.dateCreated', $criteria->dateCreated, $query->params));
     }
     if ($criteria->dateUpdated) {
         $query->andWhere(DbHelper::parseDateParam('elements.dateUpdated', $criteria->dateUpdated, $query->params));
     }
     if ($elementType->hasTitles() && $criteria->title) {
         $query->andWhere(DbHelper::parseParam('content.title', $criteria->title, $query->params));
     }
     // i18n params
     // ---------------------------------------------------------------------
     if ($criteria->slug) {
         $query->andWhere(DbHelper::parseParam('elements_i18n.slug', $criteria->slug, $query->params));
     }
     if ($criteria->uri) {
         $query->andWhere(DbHelper::parseParam('elements_i18n.uri', $criteria->uri, $query->params));
     }
     if ($criteria->localeEnabled) {
         $query->andWhere('elements_i18n.enabled = 1');
     }
     // Relational params
     // ---------------------------------------------------------------------
     // Convert the old childOf and parentOf params to the relatedTo param
     // childOf(element)  => relatedTo({ source: element })
     // parentOf(element) => relatedTo({ target: element })
     if (!$criteria->relatedTo && ($criteria->childOf || $criteria->parentOf)) {
         $relatedTo = array('and');
         if ($criteria->childOf) {
             $relatedTo[] = array('sourceElement' => $criteria->childOf, 'field' => $criteria->childField);
         }
         if ($criteria->parentOf) {
             $relatedTo[] = array('targetElement' => $criteria->parentOf, 'field' => $criteria->parentField);
         }
         $criteria->relatedTo = $relatedTo;
     }
     if ($criteria->relatedTo) {
         $relationParamParser = new ElementRelationParamParser();
         $relConditions = $relationParamParser->parseRelationParam($criteria->relatedTo, $query);
         if ($relConditions === false) {
             return false;
         }
         $query->andWhere($relConditions);
         // If there's only one relation criteria and it's specifically for grabbing target elements, allow the query
         // to order by the relation sort order
         if ($relationParamParser->isRelationFieldQuery()) {
             $query->addSelect('sources1.sortOrder');
         }
     }
     // Give field types a chance to make changes
     // ---------------------------------------------------------------------
     if ($elementType->hasContent() && $contentTable) {
         $contentService = craft()->content;
         $originalFieldColumnPrefix = $contentService->fieldColumnPrefix;
         // TODO: $fields should already be defined by now in Craft 3.0
         $fields = $elementType->getFieldsForElementsQuery($criteria);
         $extraCriteriaAttributes = $criteria->getExtraAttributeNames();
         foreach ($fields as $field) {
             $fieldType = $field->getFieldType();
             if ($fieldType) {
                 // Was this field's parameter set on the criteria model?
                 if (in_array($field->handle, $extraCriteriaAttributes)) {
                     $fieldCriteria = $criteria->{$field->handle};
                 } else {
                     $fieldCriteria = null;
                 }
                 // Set the field's column prefix on ContentService
                 if ($field->columnPrefix) {
                     $contentService->fieldColumnPrefix = $field->columnPrefix;
                 }
                 $fieldTypeResponse = $fieldType->modifyElementsQuery($query, $fieldCriteria);
                 // Set it back
                 $contentService->fieldColumnPrefix = $originalFieldColumnPrefix;
                 // Need to bail early?
                 if ($fieldTypeResponse === false) {
                     return false;
                 }
             }
         }
     }
     // Give the element type a chance to make changes
     // ---------------------------------------------------------------------
     if ($elementType->modifyElementsQuery($query, $criteria) === false) {
         return false;
     }
     // Structure params
     // ---------------------------------------------------------------------
     if ($query->isJoined('structureelements')) {
         $query->addSelect('structureelements.root, structureelements.lft, structureelements.rgt, structureelements.level');
         if ($criteria->ancestorOf) {
             if (!$criteria->ancestorOf instanceof BaseElementModel) {
                 $criteria->ancestorOf = craft()->elements->getElementById($criteria->ancestorOf, $elementType->getClassHandle(), $criteria->locale);
                 if (!$criteria->ancestorOf) {
                     return false;
                 }
             }
             if ($criteria->ancestorOf) {
                 $query->andWhere(array('and', 'structureelements.lft < :ancestorOf_lft', 'structureelements.rgt > :ancestorOf_rgt', 'structureelements.root = :ancestorOf_root'), array(':ancestorOf_lft' => $criteria->ancestorOf->lft, ':ancestorOf_rgt' => $criteria->ancestorOf->rgt, ':ancestorOf_root' => $criteria->ancestorOf->root));
                 if ($criteria->ancestorDist) {
                     $query->andWhere('structureelements.level >= :ancestorOf_level', array(':ancestorOf_level' => $criteria->ancestorOf->level - $criteria->ancestorDist));
                 }
             }
         }
         if ($criteria->descendantOf) {
             if (!$criteria->descendantOf instanceof BaseElementModel) {
                 $criteria->descendantOf = craft()->elements->getElementById($criteria->descendantOf, $elementType->getClassHandle(), $criteria->locale);
                 if (!$criteria->descendantOf) {
                     return false;
                 }
             }
             if ($criteria->descendantOf) {
                 $query->andWhere(array('and', 'structureelements.lft > :descendantOf_lft', 'structureelements.rgt < :descendantOf_rgt', 'structureelements.root = :descendantOf_root'), array(':descendantOf_lft' => $criteria->descendantOf->lft, ':descendantOf_rgt' => $criteria->descendantOf->rgt, ':descendantOf_root' => $criteria->descendantOf->root));
                 if ($criteria->descendantDist) {
                     $query->andWhere('structureelements.level <= :descendantOf_level', array(':descendantOf_level' => $criteria->descendantOf->level + $criteria->descendantDist));
                 }
             }
         }
         if ($criteria->siblingOf) {
             if (!$criteria->siblingOf instanceof BaseElementModel) {
                 $criteria->siblingOf = craft()->elements->getElementById($criteria->siblingOf, $elementType->getClassHandle(), $criteria->locale);
                 if (!$criteria->siblingOf) {
                     return false;
                 }
             }
             if ($criteria->siblingOf) {
                 $query->andWhere(array('and', 'structureelements.level = :siblingOf_level', 'structureelements.root = :siblingOf_root', 'structureelements.elementId != :siblingOf_elementId'), array(':siblingOf_level' => $criteria->siblingOf->level, ':siblingOf_root' => $criteria->siblingOf->root, ':siblingOf_elementId' => $criteria->siblingOf->id));
                 if ($criteria->siblingOf->level != 1) {
                     $parent = $criteria->siblingOf->getParent();
                     if ($parent) {
                         $query->andWhere(array('and', 'structureelements.lft > :siblingOf_lft', 'structureelements.rgt < :siblingOf_rgt'), array(':siblingOf_lft' => $parent->lft, ':siblingOf_rgt' => $parent->rgt));
                     } else {
                         return false;
                     }
                 }
             }
         }
         if ($criteria->prevSiblingOf) {
             if (!$criteria->prevSiblingOf instanceof BaseElementModel) {
                 $criteria->prevSiblingOf = craft()->elements->getElementById($criteria->prevSiblingOf, $elementType->getClassHandle(), $criteria->locale);
                 if (!$criteria->prevSiblingOf) {
                     return false;
                 }
             }
             if ($criteria->prevSiblingOf) {
                 $query->andWhere(array('and', 'structureelements.level = :prevSiblingOf_level', 'structureelements.rgt = :prevSiblingOf_rgt', 'structureelements.root = :prevSiblingOf_root'), array(':prevSiblingOf_level' => $criteria->prevSiblingOf->level, ':prevSiblingOf_rgt' => $criteria->prevSiblingOf->lft - 1, ':prevSiblingOf_root' => $criteria->prevSiblingOf->root));
             }
         }
         if ($criteria->nextSiblingOf) {
             if (!$criteria->nextSiblingOf instanceof BaseElementModel) {
                 $criteria->nextSiblingOf = craft()->elements->getElementById($criteria->nextSiblingOf, $elementType->getClassHandle(), $criteria->locale);
                 if (!$criteria->nextSiblingOf) {
                     return false;
                 }
             }
             if ($criteria->nextSiblingOf) {
                 $query->andWhere(array('and', 'structureelements.level = :nextSiblingOf_level', 'structureelements.lft = :nextSiblingOf_lft', 'structureelements.root = :nextSiblingOf_root'), array(':nextSiblingOf_level' => $criteria->nextSiblingOf->level, ':nextSiblingOf_lft' => $criteria->nextSiblingOf->rgt + 1, ':nextSiblingOf_root' => $criteria->nextSiblingOf->root));
             }
         }
         if ($criteria->positionedBefore) {
             if (!$criteria->positionedBefore instanceof BaseElementModel) {
                 $criteria->positionedBefore = craft()->elements->getElementById($criteria->positionedBefore, $elementType->getClassHandle(), $criteria->locale);
                 if (!$criteria->positionedBefore) {
                     return false;
                 }
             }
             if ($criteria->positionedBefore) {
                 $query->andWhere(array('and', 'structureelements.rgt < :positionedBefore_rgt', 'structureelements.root = :positionedBefore_root'), array(':positionedBefore_rgt' => $criteria->positionedBefore->lft, ':positionedBefore_root' => $criteria->positionedBefore->root));
             }
         }
         if ($criteria->positionedAfter) {
             if (!$criteria->positionedAfter instanceof BaseElementModel) {
                 $criteria->positionedAfter = craft()->elements->getElementById($criteria->positionedAfter, $elementType->getClassHandle(), $criteria->locale);
                 if (!$criteria->positionedAfter) {
                     return false;
                 }
             }
             if ($criteria->positionedAfter) {
                 $query->andWhere(array('and', 'structureelements.lft > :positionedAfter_lft', 'structureelements.root = :positionedAfter_root'), array(':positionedAfter_lft' => $criteria->positionedAfter->rgt, ':positionedAfter_root' => $criteria->positionedAfter->root));
             }
         }
         if ($criteria->level || $criteria->depth) {
             // TODO: 'depth' is deprecated; use 'level' instead.
             $level = $criteria->level ? $criteria->level : $criteria->depth;
             $query->andWhere(DbHelper::parseParam('structureelements.level', $level, $query->params));
         }
     }
     // Search
     // ---------------------------------------------------------------------
     if ($criteria->search) {
         $elementIds = $this->_getElementIdsFromQuery($query);
         $scoredSearchResults = $criteria->order == 'score';
         $filteredElementIds = craft()->search->filterElementIdsByQuery($elementIds, $criteria->search, $scoredSearchResults);
         // No results?
         if (!$filteredElementIds) {
             return array();
         }
         $query->andWhere(array('in', 'elements.id', $filteredElementIds));
         if ($scoredSearchResults) {
             // Order the elements in the exact order that SearchService returned them in
             $query->order(craft()->db->getSchema()->orderByColumnValues('elements.id', $filteredElementIds));
         }
     }
     return $query;
 }
 /**
  * @inheritDoc IFieldType::prepValueFromPost()
  *
  * @param mixed $value
  *
  * @return mixed
  */
 public function prepValueFromPost($value)
 {
     $dataFiles = array();
     // Grab data strings
     if (isset($value['data']) && is_array($value['data'])) {
         foreach ($value['data'] as $index => $dataString) {
             if (preg_match('/^data:(?<type>[a-z0-9]+\\/[a-z0-9]+);base64,(?<data>.+)/i', $dataString, $matches)) {
                 $type = $matches['type'];
                 $data = base64_decode($matches['data']);
                 if (!$data) {
                     continue;
                 }
                 if (!empty($value['filenames'][$index])) {
                     $filename = $value['filenames'][$index];
                 } else {
                     $extension = FileHelper::getExtensionByMimeType($type);
                     $filename = 'Uploaded file.' . $extension;
                 }
                 $dataFiles[] = array('filename' => $filename, 'data' => $data);
             }
         }
     }
     // Remove these so they don't interfere.
     if (isset($value['data']) && isset($value['filenames'])) {
         unset($value['data'], $value['filenames']);
     }
     $uploadedFiles = array();
     // See if we have uploaded file(s).
     $contentPostLocation = $this->getContentPostLocation();
     if ($contentPostLocation) {
         $files = UploadedFile::getInstancesByName($contentPostLocation);
         foreach ($files as $file) {
             $uploadedFiles[] = array('filename' => $file->getName(), 'location' => $file->getTempName());
         }
     }
     // See if we have to validate against fileKinds
     $settings = $this->getSettings();
     $allowedExtensions = false;
     if (isset($settings->restrictFiles) && !empty($settings->restrictFiles) && !empty($settings->allowedKinds)) {
         $allowedExtensions = static::_getAllowedExtensions($settings->allowedKinds);
     }
     if (is_array($allowedExtensions)) {
         foreach ($dataFiles as $file) {
             $extension = StringHelper::toLowerCase(IOHelper::getExtension($file['filename']));
             if (!in_array($extension, $allowedExtensions)) {
                 $this->_failedFiles[] = $file['filename'];
             }
         }
         foreach ($uploadedFiles as $file) {
             $extension = StringHelper::toLowerCase(IOHelper::getExtension($file['filename']));
             if (!in_array($extension, $allowedExtensions)) {
                 $this->_failedFiles[] = $file['filename'];
             }
         }
     }
     if (!empty($this->_failedFiles)) {
         return true;
     }
     // If we got here either there are no restrictions or all files are valid so let's turn them into Assets
     // Unless there are no files at all.
     if (empty($value) && empty($dataFiles) && empty($uploadedFiles)) {
         return array();
     }
     if (empty($value)) {
         $value = array();
     }
     $fileIds = array();
     if (!empty($dataFiles) || !empty($uploadedFiles)) {
         $targetFolderId = $this->_determineUploadFolderId($settings);
         foreach ($dataFiles as $file) {
             $tempPath = AssetsHelper::getTempFilePath($file['filename']);
             IOHelper::writeToFile($tempPath, $file['data']);
             $response = craft()->assets->insertFileByLocalPath($tempPath, $file['filename'], $targetFolderId);
             $fileIds[] = $response->getDataItem('fileId');
             IOHelper::deleteFile($tempPath, true);
         }
         foreach ($uploadedFiles as $file) {
             $tempPath = AssetsHelper::getTempFilePath($file['filename']);
             move_uploaded_file($file['location'], $tempPath);
             $response = craft()->assets->insertFileByLocalPath($tempPath, $file['filename'], $targetFolderId);
             $fileIds[] = $response->getDataItem('fileId');
             IOHelper::deleteFile($tempPath, true);
         }
     }
     $fileIds = array_merge($value, $fileIds);
     // Make it look like the actual POST data contained these file IDs as well,
     // so they make it into entry draft/version data
     $this->element->setRawPostContent($this->model->handle, $fileIds);
     return $fileIds;
 }
 /**
  * Rename a folder.
  *
  * @param AssetFolderModel $folder  The assetFolderModel representing the name of the folder to rename.
  * @param string           $newName The new name of the folder.
  *
  * @throws Exception
  * @return AssetOperationResponseModel
  */
 public function renameFolder(AssetFolderModel $folder, $newName)
 {
     $parentFolder = craft()->assets->getFolderById($folder->parentId);
     if (!$parentFolder) {
         throw new Exception(Craft::t("Cannot rename folder “{folder}”!", array('folder' => $folder->name)));
     }
     // Allow this for changing the case
     if (!(StringHelper::toLowerCase($newName) == StringHelper::toLowerCase($folder->name)) && $this->folderExists($parentFolder, $newName)) {
         throw new Exception(Craft::t("Folder “{folder}” already exists there.", array('folder' => $newName)));
     }
     // Try to rename the folder in the source
     if (!$this->renameSourceFolder($folder, $newName)) {
         throw new Exception(Craft::t("Cannot rename folder “{folder}”!", array('folder' => $folder->name)));
     }
     $oldFullPath = $folder->path;
     $newFullPath = IOHelper::getParentFolderPath($folder->path) . $newName . '/';
     // Find all folders with affected fullPaths and update them.
     $folders = craft()->assets->getAllDescendantFolders($folder);
     foreach ($folders as $folderModel) {
         $folderModel->path = preg_replace('#^' . $oldFullPath . '#', $newFullPath, $folderModel->path);
         craft()->assets->storeFolder($folderModel);
     }
     // Now change the affected folder
     $folder->name = $newName;
     $folder->path = $newFullPath;
     craft()->assets->storeFolder($folder);
     // All set, Scotty!
     $response = new AssetOperationResponseModel();
     return $response->setSuccess()->setDataItem('newName', $newName);
 }
Beispiel #27
0
 /**
  * Adds support for array('column' => 'value') conditional syntax. Supports nested conditionals, e.g.
  * array('or', array('column' => 'value'), array('column2' => 'value2'))
  *
  * @param mixed $conditions
  * @param array &$params
  *
  * @return mixed
  */
 private function _normalizeConditions($conditions, &$params = array())
 {
     if (!is_array($conditions)) {
         return $conditions;
     } else {
         if ($conditions === array()) {
             return '';
         }
     }
     $normalizedConditions = array();
     // Find any key/value pairs and convert them to the CDbCommand's conditional syntax
     foreach ($conditions as $key => $value) {
         if (!is_numeric($key)) {
             $param = ':p' . StringHelper::randomString(9);
             $normalizedConditions[] = $this->getConnection()->quoteColumnName($key) . '=' . $param;
             $params[$param] = $value;
             unset($conditions[$key]);
         } else {
             $conditions[$key] = $this->_normalizeConditions($value, $params);
         }
     }
     if ($normalizedConditions) {
         // Were there normal conditions in there as well?
         if ($conditions) {
             // Is this already an AND conditional?
             if (StringHelper::toLowerCase($conditions[0]) == 'and') {
                 // Just merge our normalized conditions into the $conditions
                 $conditions = array_merge($conditions, $normalizedConditions);
             } else {
                 // Append the normalized conditions as nested AND conditions
                 array_unshift($normalizedConditions, 'and');
                 $conditions[] = $normalizedConditions;
             }
         } else {
             if (count($normalizedConditions) == 1) {
                 $conditions = $normalizedConditions[0];
             } else {
                 array_unshift($normalizedConditions, 'and');
                 $conditions = $normalizedConditions;
             }
         }
     }
     return $conditions;
 }
Beispiel #28
0
 /**
  * Extracts the operator from a DB param and returns it.
  *
  * @param string &$value
  *
  * @return string
  */
 private static function _parseParamOperator(&$value)
 {
     foreach (static::$_operators as $testOperator) {
         // Does the value start with this operator?
         $operatorLength = mb_strlen($testOperator);
         if (strncmp(StringHelper::toLowerCase($value), $testOperator, $operatorLength) == 0) {
             $value = mb_substr($value, $operatorLength);
             if ($testOperator == 'not ') {
                 return '!=';
             } else {
                 return $testOperator;
             }
         }
     }
     return '=';
 }
Beispiel #29
0
 /**
  * Returns the path to the craft/app/migrations/ folder, or the path to a plugin’s migrations/ folder.
  *
  * @param string $pluginHandle The plugin handle whose migrations/ folder should be returned. Defaults to `null`.
  *
  * @return string The path to the migrations/ folder.
  */
 public function getMigrationsPath($pluginHandle = null)
 {
     if ($pluginHandle) {
         return $this->getPluginsPath() . StringHelper::toLowerCase($pluginHandle) . '/migrations/';
     }
     return $this->getAppPath() . 'migrations/';
 }
Beispiel #30
0
 /**
  * Gets the current encoding of the given string.
  *
  * @param string $string
  *
  * @return string
  */
 public static function getEncoding($string)
 {
     return StringHelper::toLowerCase(mb_detect_encoding($string, mb_detect_order(), true));
 }