/** * @param $view * @param $data * * @return mixed */ protected function render($view, $data) { if (!craft()->isConsole() && !craft()->request->isResourceRequest() && !craft()->request->isAjaxRequest() && craft()->config->get('devMode') && in_array(HeaderHelper::getMimeType(), array('text/html', 'application/xhtml+xml'))) { if (($userAgent = craft()->request->getUserAgent()) !== null && preg_match('/msie [5-9]/i', $userAgent)) { echo '<script type="text/javascript">'; echo IOHelper::getFileContents(IOHelper::getFolderName(__FILE__) . '/../vendors/console-normalizer/normalizeconsole.min.js'); echo "</script>\n"; } else { $viewFile = craft()->path->getCpTemplatesPath() . 'logging/' . $view . '-firebug.php'; include craft()->findLocalizedFile($viewFile, 'en'); } } }
/** * @param string|null $path * @param bool $fetch * * @return array */ public static function getAlerts($path = null, $fetch = false) { $alerts = array(); $user = craft()->userSession->getUser(); if (!$user) { return $alerts; } if (craft()->updates->isUpdateInfoCached() || $fetch) { // Fetch the updates regardless of whether we're on the Updates page or not, because the other alerts are // relying on cached Elliott info $updateModel = craft()->updates->getUpdates(); // Get the license key status $licenseKeyStatus = craft()->et->getLicenseKeyStatus(); // Invalid license? if ($licenseKeyStatus == LicenseKeyStatus::Invalid) { $alerts[] = Craft::t('Your license key is invalid.'); } else { if (craft()->hasWrongEdition()) { $alerts[] = Craft::t('You’re running Craft {edition} with a Craft {licensedEdition} license.', array('edition' => craft()->getEditionName(), 'licensedEdition' => craft()->getLicensedEditionName())) . ' <a class="go edition-resolution">' . Craft::t('Resolve') . '</a>'; } } if ($path != 'updates' && $user->can('performUpdates')) { if (!empty($updateModel->app->releases)) { if (craft()->updates->criticalCraftUpdateAvailable($updateModel->app->releases)) { $alerts[] = Craft::t('There’s a critical Craft update available.') . ' <a class="go nowrap" href="' . UrlHelper::getUrl('updates') . '">' . Craft::t('Go to Updates') . '</a>'; } } } // Domain mismatch? if ($licenseKeyStatus == LicenseKeyStatus::Mismatched) { $licensedDomain = craft()->et->getLicensedDomain(); $licenseKeyPath = craft()->path->getLicenseKeyPath(); $licenseKeyFile = IOHelper::getFolderName($licenseKeyPath, false) . '/' . IOHelper::getFileName($licenseKeyPath); $message = Craft::t('The license located at {file} belongs to {domain}.', array('file' => $licenseKeyFile, 'domain' => '<a href="http://' . $licensedDomain . '" target="_blank">' . $licensedDomain . '</a>')); // Can they actually do something about it? if ($user->admin) { $action = '<a class="go domain-mismatch">' . Craft::t('Transfer it to this domain') . '</a>'; } else { $action = Craft::t('Please notify one of your site’s admins.'); } $alerts[] = $message . ' ' . $action; } } $allPluginAlerts = craft()->plugins->call('getCpAlerts', array($path, $fetch), true); foreach ($allPluginAlerts as $pluginAlerts) { $alerts = array_merge($alerts, $pluginAlerts); } return $alerts; }
/** * Returns the revisioning manifest model. * * @return RevManifestModel|null */ public function getManifest() { $status = craft()->config->get('revManifest'); if (!$this->_manifest && $status !== false) { $manifestPath = craft()->config->get('revManifestPath'); if (!$manifestPath) { $manifestPath = craft()->config->get('revManifestPath', 'revmanifest'); } if (!file_exists($manifestPath)) { Craft::log(Craft::t('(Rev Manifest) The manifest file “{file}” doesn\'t exists.', array('file' => $manifestPath)), LogLevel::Error); return null; } $manifest = json_decode(file_get_contents($manifestPath), true); if (!$manifest) { Craft::log(Craft::t('(Rev Manifest) There was a problem reading the manifest file “{file}”.', array('file' => $manifestPath)), LogLevel::Error); return null; } $this->_manifest = new RevManifestModel(); $this->_manifest->manifest = $manifest; $this->_manifest->manifestFolder = IOHelper::getFolderName($manifestPath); } return $this->_manifest; }
/** * @param string|null $path * @param bool $fetch * * @return array */ public static function getAlerts($path = null, $fetch = false) { $alerts = array(); $user = craft()->userSession->getUser(); if (!$user) { return $alerts; } if (craft()->updates->isUpdateInfoCached() || $fetch) { // Fetch the updates regardless of whether we're on the Updates page or not, because the other alerts are // relying on cached Elliott info $updateModel = craft()->updates->getUpdates(); if ($path != 'updates' && $user->can('performUpdates')) { if (!empty($updateModel->app->releases)) { if (craft()->updates->criticalCraftUpdateAvailable($updateModel->app->releases)) { $alerts[] = Craft::t('There’s a critical Craft update available.') . ' <a class="go nowrap" href="' . UrlHelper::getUrl('updates') . '">' . Craft::t('Go to Updates') . '</a>'; } } } // Domain mismatch? $licenseKeyStatus = craft()->et->getLicenseKeyStatus(); if ($licenseKeyStatus == LicenseKeyStatus::MismatchedDomain) { $licensedDomain = craft()->et->getLicensedDomain(); $licenseKeyPath = craft()->path->getLicenseKeyPath(); $licenseKeyFile = IOHelper::getFolderName($licenseKeyPath, false) . '/' . IOHelper::getFileName($licenseKeyPath); $message = Craft::t('The license located at {file} belongs to {domain}.', array('file' => $licenseKeyFile, 'domain' => '<a href="http://' . $licensedDomain . '" target="_blank">' . $licensedDomain . '</a>')); // Can they actually do something about it? if ($user->admin) { $action = '<a class="domain-mismatch">' . Craft::t('Transfer it to this domain?') . '</a>'; } else { $action = Craft::t('Please notify one of your site’s admins.'); } $alerts[] = $message . ' ' . $action; } } return $alerts; }
/** * Returns all the plugins. * * @param bool $enabledOnly Whether to only return plugins that are installed and enabled. Defaults to `true`. * * @return BasePlugin[] The plugins. */ public function getPlugins($enabledOnly = true) { if ($enabledOnly) { return $this->_enabledPlugins; } else { if (!isset($this->_allPlugins)) { $this->_allPlugins = array(); // Find all of the plugins in the plugins folder $pluginsPath = craft()->path->getPluginsPath(); $pluginFolderContents = IOHelper::getFolderContents($pluginsPath, false); if ($pluginFolderContents) { foreach ($pluginFolderContents as $pluginFolderContent) { // Make sure it's actually a folder. if (IOHelper::folderExists($pluginFolderContent)) { $pluginFolderContent = IOHelper::normalizePathSeparators($pluginFolderContent); $pluginFolderName = mb_strtolower(IOHelper::getFolderName($pluginFolderContent, false)); $pluginFilePath = IOHelper::getFolderContents($pluginFolderContent, false, ".*Plugin\\.php"); if (is_array($pluginFilePath) && count($pluginFilePath) > 0) { $pluginFileName = IOHelper::getFileName($pluginFilePath[0], false); // Chop off the "Plugin" suffix $handle = mb_substr($pluginFileName, 0, mb_strlen($pluginFileName) - 6); $lcHandle = mb_strtolower($handle); // Validate that the lowercase plugin class handle is the same as the folder name // and that we haven't already loaded a plugin with the same handle but different casing if ($lcHandle === $pluginFolderName && !isset($this->_allPlugins[$lcHandle])) { $plugin = $this->getPlugin($handle, false); if ($plugin) { $this->_allPlugins[$lcHandle] = $plugin; $names[] = $plugin->getName(); } } } } } if (!empty($names)) { // Sort plugins by name array_multisort($names, $this->_allPlugins); } } } return $this->_allPlugins; } }
/** * Checks to see if the files that we are about to update are writable by Craft. * * @param string $unzipFolder * @param string $handle * * @return bool */ private function _validateManifestPathsWritable($unzipFolder, $handle) { $manifestData = UpdateHelper::getManifestData($unzipFolder, $handle); $writableErrors = array(); foreach ($manifestData as $row) { if (UpdateHelper::isManifestVersionInfoLine($row)) { continue; } $rowData = explode(';', $row); $filePath = IOHelper::normalizePathSeparators(($handle == 'craft' ? craft()->path->getAppPath() : craft()->path->getPluginsPath() . $handle . '/') . $rowData[0]); if (UpdateHelper::isManifestLineAFolder($filePath)) { $filePath = UpdateHelper::cleanManifestFolderLine($filePath); } // Check to see if the file/folder we need to update is writable. if (IOHelper::fileExists($filePath) || IOHelper::folderExists($filePath)) { if (!IOHelper::isWritable($filePath)) { $writableErrors[] = $filePath; } } else { if (($folderPath = IOHelper::folderExists(IOHelper::getFolderName($filePath))) == true) { if (!IOHelper::isWritable($folderPath)) { $writableErrors[] = $filePath; } } } } return $writableErrors; }
/** * @param $match * * @return string */ private function _normalizeCssUrl($match) { // Ignore root-relative, absolute, and data: URLs if (preg_match('/^(\\/|https?:\\/\\/|data:)/', $match[3])) { return $match[0]; } // Clean up any relative folders at the beginning of the CSS URL $requestFolder = IOHelper::getFolderName(craft()->request->getPath()); $requestFolderParts = array_filter(explode('/', $requestFolder)); $cssUrlParts = array_filter(explode('/', $match[3])); while (isset($cssUrlParts[0]) && $cssUrlParts[0] == '..' && $requestFolderParts) { array_pop($requestFolderParts); array_shift($cssUrlParts); } $pathParts = array_merge($requestFolderParts, $cssUrlParts); $path = implode('/', $pathParts); $url = UrlHelper::getUrl($path); // Is this going to be a resource URL? $rootResourceUrl = UrlHelper::getUrl(craft()->config->getResourceTrigger()) . '/'; $rootResourceUrlLength = strlen($rootResourceUrl); if (strncmp($rootResourceUrl, $url, $rootResourceUrlLength) === 0) { // Isolate the relative resource path $resourcePath = substr($url, $rootResourceUrlLength); // Give UrlHelper a chance to add the timestamp $url = UrlHelper::getResourceUrl($resourcePath); } // Return the normalized CSS URL declaration return $match[1] . $url . $match[4]; }
/** * @param $srcZip * @param $destFolder * @return bool */ public function unzip($srcZip, $destFolder) { $zip = new \PclZip($srcZip); $tempDestFolders = null; // check to see if it's a valid archive. if (($zipFiles = $zip->extract(PCLZIP_OPT_EXTRACT_AS_STRING)) == false) { Craft::log('Tried to unzip ' . $srcZip . ', but PclZip thinks it is not a valid zip archive.', LogLevel::Error); return false; } if (count($zipFiles) == 0) { Craft::log($srcZip . ' appears to be an empty zip archive.', LogLevel::Error); return false; } // find out which directories we need to create in the destination. foreach ($zipFiles as $zipFile) { if (substr($zipFile['filename'], 0, 9) === '__MACOSX/') { continue; } $folderName = IOHelper::getFolderName($zipFile['filename']); if ($folderName == './') { $tempDestFolders[] = $destFolder . '/'; } else { $tempDestFolders[] = $destFolder . '/' . rtrim(IOHelper::getFolderName($zipFile['filename']), '/'); } } $tempDestFolders = array_unique($tempDestFolders); $finalDestFolders = array(); foreach ($tempDestFolders as $tempDestFolder) { // Skip over the working directory if (rtrim($destFolder, '/') == rtrim($tempDestFolder, '/')) { continue; } // Make sure the current directory is within the working directory if (strpos($tempDestFolder, $destFolder) === false) { continue; } $finalDestFolders[] = $tempDestFolder; } asort($finalDestFolders); // Create the destination directories. foreach ($finalDestFolders as $finalDestFolder) { if (!IOHelper::folderExists($finalDestFolder)) { if (!IOHelper::createFolder($finalDestFolder)) { Craft::log('Could not create folder ' . $finalDestFolder . ' while unzipping: ' . $srcZip, LogLevel::Error); return false; } } } unset($finalDestFolders); // Extract the files from the zip foreach ($zipFiles as $zipFile) { // folders have already been created. if ($zipFile['folder']) { continue; } if (substr($zipFile['filename'], 0, 9) === '__MACOSX/') { continue; } $destFile = $destFolder . '/' . $zipFile['filename']; if (!IOHelper::writeToFile($destFile, $zipFile['content'], true, true)) { Craft::log('Could not copy the file ' . $destFile . ' while unziping: ' . $srcZip, LogLevel::Error); return false; } } return true; }
/** * @return bool */ private function _isConfigFolderWritable() { return IOHelper::isWritable(IOHelper::getFolderName(craft()->path->getLicenseKeyPath())); }
/** * @access private * @param $match * @return string */ private function _normalizeCssUrl($match) { // ignore root-relative, absolute, and data: URLs if (preg_match('/^(\\/|https?:\\/\\/|data:)/', $match[3])) { return $match[0]; } $url = IOHelper::getFolderName(craft()->request->getPath()) . $match[3]; // Make sure this is a resource URL $resourceTrigger = craft()->config->get('resourceTrigger'); $resourceTriggerPos = strpos($url, $resourceTrigger); if ($resourceTriggerPos !== false) { // Give UrlHelper a chance to add the timestamp $path = substr($url, $resourceTriggerPos + strlen($resourceTrigger)); $url = UrlHelper::getResourceUrl($path); } return $match[1] . $url . $match[4]; }
/** * @param bool $fullPath * @return mixed */ public function getFolderName($fullPath = true) { if ($fullPath) { if (!$this->_fullFolderName) { $this->_fullFolderName = IOHelper::getFolderName($this->getRealPath(), $fullPath); } return $this->_fullFolderName; } else { if (!$this->_folderNameOnly) { $this->_folderNameOnly = IOHelper::getFolderName($this->getRealPath(), $fullPath); } return $this->_folderNameOnly; } }
/** * @param $tempFileName * @param $originalSize * @param $extension * @param $minQuality * @param $maxQuality * @param int $step * * @return bool */ private function _autoGuessImageQuality($tempFileName, $originalSize, $extension, $minQuality, $maxQuality, $step = 0) { // Give ourselves some extra time. @set_time_limit(30); if ($step == 0) { $tempFileName = IOHelper::getFolderName($tempFileName).IOHelper::getFileName($tempFileName, false).'-temp.'.$extension; } // Find our target quality by splitting the min and max qualities $midQuality = (int)ceil($minQuality + (($maxQuality - $minQuality) / 2)); // Set the min and max acceptable ranges. .10 means anything between 90% and 110% of the original file size is acceptable. $acceptableRange = .10; clearstatcache(); // Generate a new temp image and get it's file size. $this->_image->save($tempFileName, $this->_getSaveOptions($midQuality, $extension)); $newFileSize = IOHelper::getFileSize($tempFileName); // If we're on step 10 OR we're within our acceptable range threshold OR midQuality = maxQuality (1 == 1), // let's use the current image. if ($step == 10 || abs(1 - $originalSize / $newFileSize) < $acceptableRange || $midQuality == $maxQuality) { clearstatcache(); // Generate one last time. $this->_image->save($tempFileName, $this->_getSaveOptions($midQuality)); return true; } $step++; if ($newFileSize > $originalSize) { return $this->_autoGuessImageQuality($tempFileName, $originalSize, $extension, $minQuality, $midQuality, $step); } // Too much. else { return $this->_autoGuessImageQuality($tempFileName, $originalSize, $extension, $midQuality, $maxQuality, $step); } }
/** * Stores a value identified by a key in cache. This is the implementation of the method declared in the parent class. * * @param string $key The key identifying the value to be cached * @param string $value The value to be cached * @param integer $expire The number of seconds in which the cached value will expire. 0 means never expire. * @return boolean true If the value is successfully stored into cache, false otherwise */ protected function setValue($key, $value, $expire) { if (!$this->_gced && mt_rand(0, 1000000) < $this->getGCProbability()) { $this->gc(); $this->_gced = true; } if ($expire <= 0) { $expire = 31536000; // 1 year } $expire += time(); $cacheFile = $this->getCacheFile($key); if ($this->directoryLevel > 0) { IOHelper::createFolder(IOHelper::getFolderName($cacheFile), IOHelper::getWritableFolderPermissions()); } if ($this->_originalKey == 'useWriteFileLock') { if (IOHelper::writeToFile($cacheFile, $value, true, false, true) !== false) { IOHelper::changePermissions($cacheFile, IOHelper::getWritableFilePermissions()); return IOHelper::touch($cacheFile, $expire); } else { return false; } } else { if (IOHelper::writeToFile($cacheFile, $value) !== false) { IOHelper::changePermissions($cacheFile, IOHelper::getWritableFilePermissions()); return IOHelper::touch($cacheFile, $expire); } else { return false; } } }
/** * Creates a new support ticket for the GetHelp widget. * * @return null */ public function actionSendSupportRequest() { $this->requirePostRequest(); craft()->config->maxPowerCaptain(); $success = false; $errors = array(); $zipFile = null; $tempFolder = null; $widgetId = craft()->request->getPost('widgetId'); $namespace = craft()->request->getPost('namespace'); $namespace = $namespace ? $namespace . '.' : ''; $getHelpModel = new GetHelpModel(); $getHelpModel->fromEmail = craft()->request->getPost($namespace . 'fromEmail'); $getHelpModel->message = trim(craft()->request->getPost($namespace . 'message')); $getHelpModel->attachLogs = (bool) craft()->request->getPost($namespace . 'attachLogs'); $getHelpModel->attachDbBackup = (bool) craft()->request->getPost($namespace . 'attachDbBackup'); $getHelpModel->attachTemplates = (bool) craft()->request->getPost($namespace . 'attachTemplates'); $getHelpModel->attachment = UploadedFile::getInstanceByName($namespace . 'attachAdditionalFile'); if ($getHelpModel->validate()) { $user = craft()->userSession->getUser(); // Add some extra info about this install $message = $getHelpModel->message . "\n\n" . "------------------------------\n\n" . 'Craft ' . craft()->getEditionName() . ' ' . craft()->getVersion() . '.' . craft()->getBuild(); $plugins = craft()->plugins->getPlugins(); if ($plugins) { $pluginNames = array(); foreach ($plugins as $plugin) { $pluginNames[] = $plugin->getName() . ' ' . $plugin->getVersion() . ' (' . $plugin->getDeveloper() . ')'; } $message .= "\nPlugins: " . implode(', ', $pluginNames); } $requestParamDefaults = array('sFirstName' => $user->getFriendlyName(), 'sLastName' => $user->lastName ? $user->lastName : 'Doe', 'sEmail' => $getHelpModel->fromEmail, 'tNote' => $message); $requestParams = $requestParamDefaults; $hsParams = array('helpSpotApiURL' => 'https://support.pixelandtonic.com/api/index.php'); try { if ($getHelpModel->attachLogs || $getHelpModel->attachDbBackup) { if (!$zipFile) { $zipFile = $this->_createZip(); } if ($getHelpModel->attachLogs && IOHelper::folderExists(craft()->path->getLogPath())) { // Grab it all. $logFolderContents = IOHelper::getFolderContents(craft()->path->getLogPath()); foreach ($logFolderContents as $file) { // Make sure it's a file. if (IOHelper::fileExists($file)) { Zip::add($zipFile, $file, craft()->path->getStoragePath()); } } } if ($getHelpModel->attachDbBackup && IOHelper::folderExists(craft()->path->getDbBackupPath())) { // Make a fresh database backup of the current schema/data. We want all data from all tables // for debugging. craft()->db->backup(); $backups = IOHelper::getLastModifiedFiles(craft()->path->getDbBackupPath(), 3); foreach ($backups as $backup) { if (IOHelper::getExtension($backup) == 'sql') { Zip::add($zipFile, $backup, craft()->path->getStoragePath()); } } } } if ($getHelpModel->attachment) { // If we don't have a zip file yet, create one now. if (!$zipFile) { $zipFile = $this->_createZip(); } $tempFolder = craft()->path->getTempPath() . StringHelper::UUID() . '/'; if (!IOHelper::folderExists($tempFolder)) { IOHelper::createFolder($tempFolder); } $tempFile = $tempFolder . $getHelpModel->attachment->getName(); $getHelpModel->attachment->saveAs($tempFile); // Make sure it actually saved. if (IOHelper::fileExists($tempFile)) { Zip::add($zipFile, $tempFile, $tempFolder); } } if ($getHelpModel->attachTemplates) { // If we don't have a zip file yet, create one now. if (!$zipFile) { $zipFile = $this->_createZip(); } if (IOHelper::folderExists(craft()->path->getLogPath())) { // Grab it all. $templateFolderContents = IOHelper::getFolderContents(craft()->path->getSiteTemplatesPath()); foreach ($templateFolderContents as $file) { // Make sure it's a file. if (IOHelper::fileExists($file)) { $templateFolderName = IOHelper::getFolderName(craft()->path->getSiteTemplatesPath(), false); $siteTemplatePath = craft()->path->getSiteTemplatesPath(); $tempPath = substr($siteTemplatePath, 0, strlen($siteTemplatePath) - strlen($templateFolderName) - 1); Zip::add($zipFile, $file, $tempPath); } } } } if ($zipFile) { $requestParams['File1_sFilename'] = 'SupportAttachment-' . IOHelper::cleanFilename(craft()->getSiteName()) . '.zip'; $requestParams['File1_sFileMimeType'] = 'application/zip'; $requestParams['File1_bFileBody'] = base64_encode(IOHelper::getFileContents($zipFile)); // Bump the default timeout because of the attachment. $hsParams['callTimeout'] = 120; } // Grab the license.key file. if (IOHelper::fileExists(craft()->path->getLicenseKeyPath())) { $requestParams['File2_sFilename'] = 'license.key'; $requestParams['File2_sFileMimeType'] = 'text/plain'; $requestParams['File2_bFileBody'] = base64_encode(IOHelper::getFileContents(craft()->path->getLicenseKeyPath())); } } catch (\Exception $e) { Craft::log('Tried to attach debug logs to a support request and something went horribly wrong: ' . $e->getMessage(), LogLevel::Warning); // There was a problem zipping, so reset the params and just send the email without the attachment. $requestParams = $requestParamDefaults; } require_once craft()->path->getLibPath() . 'HelpSpotAPI.php'; $hsapi = new \HelpSpotAPI($hsParams); $result = $hsapi->requestCreate($requestParams); if ($result) { if ($zipFile) { if (IOHelper::fileExists($zipFile)) { IOHelper::deleteFile($zipFile); } } if ($tempFolder) { IOHelper::clearFolder($tempFolder); IOHelper::deleteFolder($tempFolder); } $success = true; } else { $hsErrors = array_filter(preg_split("/(\r\n|\n|\r)/", $hsapi->errors)); $errors = array('Support' => $hsErrors); } } else { $errors = $getHelpModel->getErrors(); } $this->renderTemplate('_components/widgets/GetHelp/response', array('success' => $success, 'errors' => JsonHelper::encode($errors), 'widgetId' => $widgetId)); }
/** * @static * @param bool $fetch * @return array */ public static function getAlerts($path = null, $fetch = false) { $alerts = array(); $user = craft()->userSession->getUser(); if (!$user) { return $alerts; } if (craft()->updates->isUpdateInfoCached() || $fetch) { // Fetch the updates regardless of whether we're on the Updates page or not, // because the other alerts are relying on cached Elliott info $updateModel = craft()->updates->getUpdates(); if ($path != 'updates' && $user->can('performUpdates')) { if (!empty($updateModel->app->releases)) { if (craft()->updates->criticalCraftUpdateAvailable($updateModel->app->releases)) { $alerts[] = Craft::t('There’s a critical Craft update available.') . ' <a class="go" href="' . UrlHelper::getUrl('updates') . '">' . Craft::t('Go to Updates') . '</a>'; } } } // Domain mismatch? $licenseKeyStatus = craft()->et->getLicenseKeyStatus(); if ($licenseKeyStatus == LicenseKeyStatus::MismatchedDomain) { $licensedDomain = craft()->et->getLicensedDomain(); $licenseKeyPath = craft()->path->getLicenseKeyPath(); $licenseKeyFile = IOHelper::getFolderName($licenseKeyPath, false) . '/' . IOHelper::getFileName($licenseKeyPath); $message = Craft::t('The license located at {file} belongs to {domain}.', array('file' => $licenseKeyFile, 'domain' => '<a href="http://' . $licensedDomain . '" target="_blank">' . $licensedDomain . '</a>')); // Can they actually do something about it? if ($user->admin) { $action = '<a class="domain-mismatch">' . Craft::t('Transfer it to this domain?') . '</a>'; } else { $action = Craft::t('Please notify one of your site’s admins.'); } $alerts[] = $message . ' ' . $action; } // Unlicensed packages? if ($path != 'settings/packages') { $licensedPackages = craft()->et->getLicensedPackages(); $packageTrials = craft()->et->getPackageTrials(); // Could be false if not cached if (is_array($licensedPackages)) { // Look for any unlicensed licenses $unlicensedPackages = array(); foreach (Craft::getPackages() as $package) { if (!in_array($package, $licensedPackages)) { // Make sure it's not in trial if (!is_array($packageTrials) || !in_array($package, array_keys($packageTrials))) { $unlicensedPackages[] = $package; } } } if ($unlicensedPackages) { if (count($unlicensedPackages) == 1) { $message = Craft::t('The {package} package is installed, but it’s not licensed.', array('package' => Craft::t($unlicensedPackages[0]))); } else { $message = Craft::t('You have multiple unlicensed packages installed.'); } // Can they actually do something about it? if ($user->admin) { $action = '<a class="go" href="' . UrlHelper::getUrl('settings/packages') . '">' . Craft::t('Manage packages') . '</a>'; } else { $action = Craft::t('Please notify one of your site’s admins.'); } $alerts[] = $message . ' ' . $action; } } if ($packageTrials && $user->admin && !$user->hasShunned('packageTrialAlert')) { $expiringTrials = array(); $currentTime = DateTimeHelper::currentUTCDateTime(); $nextWeek = $currentTime->add(new DateInterval('P1W'))->getTimestamp(); // See if there are any package trials that expire in less than a week foreach (Craft::getPackages() as $package) { if (!empty($packageTrials[$package])) { if ($packageTrials[$package] < $nextWeek) { $expiringTrials[] = $package; } } } if ($expiringTrials) { if (count($expiringTrials) == 1) { $message = Craft::t('Your {package} trial is expiring soon.', array('package' => Craft::t($expiringTrials[0]))); } else { $message = Craft::t('You have multiple package trials expiring soon.'); } $action1 = '<a class="shun:packageTrialAlert">' . Craft::t('Remind me later') . '</a>'; $action2 = '<a class="go" href="' . UrlHelper::getUrl('settings/packages') . '">' . Craft::t('manage packages') . '</a>'; $alerts[] = $message . ' ' . $action1 . ' ' . Craft::t('or') . ' ' . $action2; } } } } return $alerts; }
/** * Returns all the plugins. * * @param bool $enabledOnly Whether to only return plugins that are installed and enabled. Defaults to `true`. * * @return BasePlugin[] The plugins. */ public function getPlugins($enabledOnly = true) { if ($enabledOnly) { return $this->_enabledPlugins; } else { if (!isset($this->_allPlugins)) { $this->_allPlugins = array(); // Find all of the plugins in the plugins folder $pluginsPath = craft()->path->getPluginsPath(); $pluginFolderContents = IOHelper::getFolderContents($pluginsPath, false); if ($pluginFolderContents) { foreach ($pluginFolderContents as $pluginFolderContent) { // Make sure it's actually a folder. if (IOHelper::folderExists($pluginFolderContent)) { $pluginFolderContent = IOHelper::normalizePathSeparators($pluginFolderContent); $pluginFolderName = mb_strtolower(IOHelper::getFolderName($pluginFolderContent, false)); $pluginFilePath = IOHelper::getFolderContents($pluginFolderContent, false, ".*Plugin\\.php"); if (is_array($pluginFilePath) && count($pluginFilePath) > 0) { $pluginFileName = IOHelper::getFileName($pluginFilePath[0], false); // Chop off the "Plugin" suffix $handle = mb_substr($pluginFileName, 0, mb_strlen($pluginFileName) - 6); if (mb_strtolower($handle) === mb_strtolower($pluginFolderName)) { $plugin = $this->getPlugin($handle, false); if ($plugin) { $this->_allPlugins[mb_strtolower($handle)] = $plugin; $names[] = $plugin->getName(); } } } } } if (!empty($names)) { // Sort plugins by name array_multisort($names, $this->_allPlugins); } } } return $this->_allPlugins; } }