/** * @return array * @throws Exception */ public function processDownload() { Craft::log('Starting to process the update download.', LogLevel::Info, true); $tempPath = craft()->path->getTempPath(); // Download the package from ET. Craft::log('Downloading patch file to ' . $tempPath, LogLevel::Info, true); if (($fileName = craft()->et->downloadUpdate($tempPath)) !== false) { $downloadFilePath = $tempPath . $fileName; } else { throw new Exception(Craft::t('There was a problem downloading the package.')); } $uid = StringHelper::UUID(); // Validate the downloaded update against ET. Craft::log('Validating downloaded update.', LogLevel::Info, true); if (!$this->_validateUpdate($downloadFilePath)) { throw new Exception(Craft::t('There was a problem validating the downloaded package.')); } // Unpack the downloaded package. Craft::log('Unpacking the downloaded package.', LogLevel::Info, true); $unzipFolder = craft()->path->getTempPath() . $uid; if (!$this->_unpackPackage($downloadFilePath, $unzipFolder)) { throw new Exception(Craft::t('There was a problem unpacking the downloaded package.')); } return array('uid' => $uid); }
/** * @param SproutSeo_SitemapModel $attributes * * @return mixed|null|string */ public function saveSitemap(SproutSeo_SitemapModel $attributes) { $row = array(); $isNew = false; if (isset($attributes->id) && substr($attributes->id, 0, 3) === "new") { $isNew = true; } if (!$isNew) { $row = craft()->db->createCommand()->select('*')->from('sproutseo_sitemap')->where('id=:id', array(':id' => $attributes->id))->queryRow(); } $model = SproutSeo_SitemapModel::populateModel($row); $model->id = !$isNew ? $attributes->id : null; $model->sectionId = isset($attributes->sectionId) ? $attributes->sectionId : null; $model->url = isset($attributes->url) ? $attributes->url : null; $model->priority = $attributes->priority; $model->changeFrequency = $attributes->changeFrequency; $model->enabled = $attributes->enabled == 'true' ? 1 : 0; $model->ping = $attributes->ping == 'true' ? 1 : 0; $model->dateUpdated = DateTimeHelper::currentTimeForDb(); $model->uid = StringHelper::UUID(); if ($isNew) { $model->dateCreated = DateTimeHelper::currentTimeForDb(); craft()->db->createCommand()->insert('sproutseo_sitemap', $model->getAttributes()); return craft()->db->lastInsertID; } else { $result = craft()->db->createCommand()->update('sproutseo_sitemap', $model->getAttributes(), 'id=:id', array(':id' => $model->id)); return $model->id; } }
/** * @param $downloadPath * @return bool */ public function downloadUpdate($downloadPath) { $et = new Et(static::DownloadUpdate, 240); if (IOHelper::folderExists($downloadPath)) { $downloadPath .= StringHelper::UUID() . '.zip'; } $et->setDestinationFileName($downloadPath); if (($fileName = $et->phoneHome()) !== null) { return $fileName; } return false; }
public function addCacheById($cacheId, $flags) { $flags = craft()->cacheFlag->sanitizeFlags($flags); $transaction = craft()->db->getCurrentTransaction() === null ? craft()->db->beginTransaction() : null; try { craft()->db->createCommand()->insert('templatecaches_flagged', array('cacheId' => $cacheId, 'flags' => $flags, 'uid' => StringHelper::UUID(), 'dateCreated' => date('Y-m-d H:i:s'), 'dateUpdated' => date('Y-m-d H:i:s')), false); if ($transaction !== null) { $transaction->commit(); } } catch (\Exception $e) { if ($transaction !== null) { $transaction->rollback(); } throw $e; } }
/** * @param string $unzipFolder * * @throws Exception * @return array */ private function _validateNewRequirements($unzipFolder) { $requirementsFolderPath = $unzipFolder . '/app/etc/requirements/'; $requirementsFile = $requirementsFolderPath . 'Requirements.php'; $errors = array(); if (!IOHelper::fileExists($requirementsFile)) { throw new Exception(Craft::t('The Requirements file is required and it does not exist at {path}.', array('path' => $requirementsFile))); } // Make sure we can write to craft/app/requirements if (!IOHelper::isWritable(craft()->path->getAppPath() . 'etc/requirements/')) { throw new Exception(StringHelper::parseMarkdown(Craft::t('Craft CMS needs to be able to write to your craft/app/etc/requirements folder and cannot. Please check your [permissions]({url}).', array('url' => 'http://craftcms.com/docs/updating#one-click-updating')))); } $tempFileName = StringHelper::UUID() . '.php'; // Make a dupe of the requirements file and give it a random file name. IOHelper::copyFile($requirementsFile, $requirementsFolderPath . $tempFileName); $newTempFilePath = craft()->path->getAppPath() . 'etc/requirements/' . $tempFileName; // Copy the random file name requirements to the requirements folder. // We don't want to execute any PHP from the storage folder. IOHelper::copyFile($requirementsFolderPath . $tempFileName, $newTempFilePath); require_once $newTempFilePath; $checker = new RequirementsChecker(); $checker->run(); if ($checker->getResult() == RequirementResult::Failed) { foreach ($checker->getRequirements() as $requirement) { if ($requirement->getResult() == InstallStatus::Failed) { Craft::log('Requirement "' . $requirement->getName() . '" failed with the message: ' . $requirement->getNotes(), LogLevel::Error, true); $errors[] = $requirement->getNotes(); } } } // Cleanup IOHelper::deleteFile($newTempFilePath); return $errors; }
/** * @param $manifestData * @param $sourceTempFolder * @param $handle * * @return bool */ public static function doFileUpdate($manifestData, $sourceTempFolder, $handle) { if ($handle == 'craft') { $destDirectory = craft()->path->getAppPath(); $sourceFileDirectory = 'app/'; } else { $destDirectory = craft()->path->getPluginsPath() . $handle . '/'; $sourceFileDirectory = ''; } try { foreach ($manifestData as $row) { if (static::isManifestVersionInfoLine($row)) { continue; } $folder = false; $rowData = explode(';', $row); if (static::isManifestLineAFolder($rowData[0])) { $folder = true; $tempPath = static::cleanManifestFolderLine($rowData[0]); } else { $tempPath = $rowData[0]; } $destFile = IOHelper::normalizePathSeparators($destDirectory . $tempPath); $sourceFile = IOHelper::getRealPath(IOHelper::normalizePathSeparators($sourceTempFolder . '/' . $sourceFileDirectory . $tempPath)); switch (trim($rowData[1])) { // update the file case PatchManifestFileAction::Add: if ($folder) { Craft::log('Updating folder: ' . $destFile, LogLevel::Info, true); $tempFolder = rtrim($destFile, '/') . StringHelper::UUID() . '/'; $tempTempFolder = rtrim($destFile, '/') . '-tmp/'; IOHelper::createFolder($tempFolder); IOHelper::copyFolder($sourceFile, $tempFolder); IOHelper::rename($destFile, $tempTempFolder); IOHelper::rename($tempFolder, $destFile); IOHelper::clearFolder($tempTempFolder); IOHelper::deleteFolder($tempTempFolder); } else { Craft::log('Updating file: ' . $destFile, LogLevel::Info, true); IOHelper::copyFile($sourceFile, $destFile); } break; } } } catch (\Exception $e) { Craft::log('Error updating files: ' . $e->getMessage(), LogLevel::Error); UpdateHelper::rollBackFileChanges($manifestData, $handle); return false; } return true; }
/** * Sets a user record up for a new verification code without saving it. * * @param UserRecord $userRecord * * @return string */ private function _setVerificationCodeOnUserRecord(UserRecord $userRecord) { $unhashedCode = StringHelper::UUID(); $hashedCode = craft()->security->hashPassword($unhashedCode); $userRecord->verificationCode = $hashedCode; $userRecord->verificationCodeIssuedDate = DateTimeHelper::currentUTCDateTime(); return $unhashedCode; }
/** * @param string $table * @param array $keyColumns * @param array $updateColumns * @param bool $includeAuditColumns * * @return int */ public function insertOrUpdate($table, $keyColumns, $updateColumns, $includeAuditColumns = true) { if ($includeAuditColumns) { $keyColumns['dateCreated'] = DateTimeHelper::currentTimeForDb(); $keyColumns['uid'] = StringHelper::UUID(); $updateColumns['dateUpdated'] = DateTimeHelper::currentTimeForDb(); } // TODO: This is all MySQL specific $allColumns = array_merge($keyColumns, $updateColumns); $params = array(); $table = $this->getConnection()->addTablePrefix($table); $sql = 'INSERT INTO ' . $this->getConnection()->quoteTableName($table) . ' ('; foreach (array_keys($allColumns) as $i => $column) { if ($i > 0) { $sql .= ', '; } $sql .= $this->getConnection()->quoteColumnName($column); $params[':' . $column] = $allColumns[$column]; } $sql .= ') VALUES (:' . implode(', :', array_keys($allColumns)) . ')' . ' ON DUPLICATE KEY UPDATE '; foreach (array_keys($updateColumns) as $i => $column) { if ($i > 0) { $sql .= ', '; } $sql .= $this->getConnection()->quoteColumnName($column) . ' = :' . $column; } return $this->setText($sql)->execute($params); }
/** * Restores a user session from the identity cookie. * * This method is used when automatic login ({@link allowAutoLogin}) is enabled. The user identity information is * recovered from cookie. * * @todo Verify that it's totally necessary to re-save the cookie with a new user session token * @return null */ protected function restoreFromCookie() { // If this request doesn't want to extend the user session, it is unfortunately not possible for us to restore // their user session from a cookie, because the cookie needs to be re-saved with a new user session token, // but we can't do that without also setting a new expiration date. if ($this->_dontExtendSession) { return; } // See if they have an existing identity cookie. $cookie = $this->getIdentityCookie(); if ($cookie) { $data = $this->getIdentityCookieValue($cookie); if ($data && $this->_checkUserAgentString($data[4])) { $loginName = $data[0]; $currentSessionToken = $data[1]; $uid = $data[2]; $rememberMe = $data[3]; $states = $data[5]; $currentUserAgent = craft()->request->userAgent; $this->authTimeout = craft()->config->getUserSessionDuration($rememberMe); // Get the hashed token from the db based on login name and uid. if (($sessionRow = $this->_findSessionToken($loginName, $uid)) !== false) { $dbHashedToken = $sessionRow['token']; $userId = $sessionRow['userId']; // Make sure the given session token matches what we have in the db. $checkHashedToken = craft()->security->hashData(base64_encode(serialize($currentSessionToken))); if (strcmp($checkHashedToken, $dbHashedToken) === 0) { // It's all good. if ($this->beforeLogin($loginName, $states, true)) { $this->changeIdentity($userId, $loginName, $states); if ($this->autoRenewCookie) { // Generate a new session token for the database and cookie. $newSessionToken = StringHelper::UUID(); $hashedNewToken = craft()->security->hashData(base64_encode(serialize($newSessionToken))); $this->_updateSessionToken($loginName, $dbHashedToken, $hashedNewToken); // While we're let's clean up stale sessions. $this->_cleanStaleSessions(); // Save updated info back to identity cookie. $data = array($this->getName(), $newSessionToken, $uid, $rememberMe ? 1 : 0, $currentUserAgent, $states); $this->_identityCookie = $this->saveCookie('', $data, $this->authTimeout); $this->_sessionRestoredFromCookie = true; $this->_userRow = null; } $this->afterLogin(true); } } else { Craft::log('Tried to restore session from a cookie, but the given hashed database token value does not appear to belong to the given login name. Hashed db value: ' . $dbHashedToken . ' and loginName: ' . $loginName . '.', LogLevel::Warning); // Forcing logout here clears the identity cookie helping to prevent session fixation. $this->logout(true); } } else { Craft::log('Tried to restore session from a cookie, but the given login name does not match the given uid. UID: ' . $uid . ' and loginName: ' . $loginName . '.', LogLevel::Warning); // Forcing logout here clears the identity cookie helping to prevent session fixation. $this->logout(true); } } else { Craft::log('Tried to restore session from a cookie, but it appears we the data in the cookie is invalid.', LogLevel::Warning); $this->logout(true); } } }
/** * Creates a new support ticket for the GetHelp widget. */ public function actionSendSupportRequest() { $this->requirePostRequest(); $this->requireAjaxRequest(); craft()->config->maxPowerCaptain(); $getHelpModel = new GetHelpModel(); $getHelpModel->fromEmail = craft()->request->getPost('fromEmail'); $getHelpModel->message = craft()->request->getPost('message'); $getHelpModel->attachDebugFiles = (bool) craft()->request->getPost('attachDebugFiles'); if ($getHelpModel->validate()) { $user = craft()->userSession->getUser(); $requestParamDefaults = array('sFirstName' => $user->getFriendlyName(), 'sLastName' => $user->lastName ? $user->lastName : 'Doe', 'sEmail' => $getHelpModel->fromEmail, 'tNote' => $getHelpModel->message); $requestParams = $requestParamDefaults; $hsParams = array('helpSpotApiURL' => 'https://support.pixelandtonic.com/api/index.php'); try { if ($getHelpModel->attachDebugFiles) { $tempZipFile = craft()->path->getTempPath() . StringHelper::UUID() . '.zip'; IOHelper::createFile($tempZipFile); if (IOHelper::folderExists(craft()->path->getLogPath())) { // Grab the latest log file. Zip::add($tempZipFile, craft()->path->getLogPath() . 'craft.log', craft()->path->getStoragePath()); // Grab the most recent rolled-over log file, if one exists. if (IOHelper::fileExists(craft()->path->getLogPath() . 'craft.log.1')) { Zip::add($tempZipFile, craft()->path->getLogPath() . 'craft.log.1', craft()->path->getStoragePath()); } // Grab the phperrors log file, if it exists. if (IOHelper::fileExists(craft()->path->getLogPath() . 'phperrors.log')) { Zip::add($tempZipFile, craft()->path->getLogPath() . 'phperrors.log', craft()->path->getStoragePath()); } } if (IOHelper::folderExists(craft()->path->getDbBackupPath())) { // Make a fresh database backup of the current schema/data. craft()->db->backup(); $contents = IOHelper::getFolderContents(craft()->path->getDbBackupPath()); rsort($contents); // Only grab the most recent 3 sorted by timestamp. for ($counter = 0; $counter <= 2; $counter++) { if (isset($contents[$counter])) { Zip::add($tempZipFile, $contents[$counter], craft()->path->getStoragePath()); } } } $requestParams['File1_sFilename'] = 'SupportAttachment.zip'; $requestParams['File1_sFileMimeType'] = 'application/zip'; $requestParams['File1_bFileBody'] = base64_encode(IOHelper::getFileContents($tempZipFile)); // Bump the default timeout because of the attachment. $hsParams['callTimeout'] = 120; } } 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 ($getHelpModel->attachDebugFiles) { if (IOHelper::fileExists($tempZipFile)) { IOHelper::deleteFile($tempZipFile); } } $this->returnJson(array('success' => true)); } else { $hsErrors = array_filter(preg_split("/(\r\n|\n|\r)/", $hsapi->errors)); $this->returnJson(array('errors' => array('Support' => $hsErrors))); } } else { $this->returnJson(array('errors' => $getHelpModel->getErrors())); } }
/** * @return string */ private function _createZip() { $zipFile = craft()->path->getTempPath() . StringHelper::UUID() . '.zip'; IOHelper::createFile($zipFile); return $zipFile; }
/** * Populates the current user object with the information obtained from cookie. * This method is used when automatic login ({@link allowAutoLogin}) is enabled. * The user identity information is recovered from cookie. */ protected function restoreFromCookie() { $this->_checkVitals(); // See if they have an existing identity cookie. $cookie = craft()->request->getCookies()->itemAt($this->getStateKeyPrefix()); // Grab the identity cookie and make sure the data hasn't been tampered with. if ($cookie && !empty($cookie->value) && is_string($cookie->value) && ($data = craft()->securityManager->validateData($cookie->value)) !== false) { // Grab the data $data = $this->getCookieValue(''); if (is_array($data) && isset($data[0], $data[1], $data[2], $data[3], $data[4], $data[5])) { $loginName = $data[0]; $currentSessionToken = $data[1]; $uid = $data[2]; $seconds = $data[3]; $savedUserAgent = $data[4]; $states = $data[5]; $currentUserAgent = craft()->request->userAgent; $this->_checkUserAgentString($currentUserAgent, $savedUserAgent); // Get the hashed token from the db based on login name and uid. if (($sessionRow = $this->_findSessionToken($loginName, $uid)) !== false) { $dbHashedToken = $sessionRow['token']; $userId = $sessionRow['userId']; // Make sure the given session token matches what we have in the db. if (craft()->security->checkString($currentSessionToken, $dbHashedToken)) { // It's all good. if ($this->beforeLogin($loginName, $states, true)) { $this->changeIdentity($userId, $loginName, $states); if ($this->autoRenewCookie) { // Generate a new session token for the database and cookie. $newSessionToken = StringHelper::UUID(); $hashedNewToken = craft()->security->hashString($newSessionToken); $this->_updateSessionToken($loginName, $dbHashedToken, $hashedNewToken['hash']); // While we're let's clean up stale sessions. $this->_cleanStaleSessions(); // Save updated info back to identity cookie. $data = array($this->getName(), $newSessionToken, $uid, $seconds, $currentUserAgent, $states); $this->saveCookie('', $data, $seconds); $this->authTimeout = $seconds; $this->_sessionRestoredFromCookie = true; $this->_userRow = null; } $this->afterLogin(true); } } else { Craft::log('Tried to restore session from a cookie, but the given hashed database token value does not appear to belong to the given login name. Hashed db value: ' . $dbHashedToken . ' and loginName: ' . $loginName . '.', LogLevel::Error); // Forcing logout here clears the identity cookie helping to prevent session fixation. $this->logout(); } } else { Craft::log('Tried to restore session from a cookie, but the given login name does not match the given uid. UID: ' . $uid . ' and loginName: ' . $loginName . '.', LogLevel::Error); // Forcing logout here clears the identity cookie helping to prevent session fixation. $this->logout(); } } else { Craft::log('Tried to restore session from a cookie, but it appears we the data in the cookie is invalid.', LogLevel::Error); $this->logout(); } } else { // If session duration is set to 0, then the session will be over when the browser is closed. if ($this->_getSessionDuration(false) > 0) { // If they are not a guest, they still have a valid PHP session, but at this point their identity cookie has expired, so let's kill it all. if (!$this->isGuest()) { $this->logout(false); } } } }
private function _storeFile(EmbeddedAssetsModel $media, $folderId) { $fileName = EmbeddedAssetsPlugin::getFileNamePrefix() . StringHelper::UUID() . '.json'; $fileData = $media->getAttributes(null, true); $fileData['__embeddedasset__'] = true; unset($fileData['id']); unset($fileData['settings']); $this->_addToFiles('assets-upload', $fileName, JsonHelper::encode($fileData)); $response = craft()->assets->uploadFile($folderId); if ($response->isSuccess()) { $fileId = $response->getDataItem('fileId'); $file = craft()->assets->getFileById($fileId); return $file; } else { throw new \Exception($response->errorMessage); } }
/** * Prepares the model's attribute values to be saved to the database. * * @return null */ public function prepAttributesForSave() { $attributes = $this->getAttributeConfigs(); $attributes['dateUpdated'] = array('type' => AttributeType::DateTime, 'column' => ColumnType::DateTime, 'required' => true); $attributes['dateCreated'] = array('type' => AttributeType::DateTime, 'column' => ColumnType::DateTime, 'required' => true); foreach ($attributes as $name => $config) { $value = $this->getAttribute($name); if ($config['type'] == AttributeType::DateTime) { // Leaving this in because we want to allow plugin devs to save a timestamp or DateTime object. if (DateTimeHelper::isValidTimeStamp($value)) { $value = new DateTime('@' . $value); } } $this->setAttribute($name, ModelHelper::packageAttributeValue($value, true)); } // Populate dateCreated and uid if this is a new record if ($this->isNewRecord()) { $this->dateCreated = DateTimeHelper::currentTimeForDb(); $this->uid = StringHelper::UUID(); } // Update the dateUpdated $this->dateUpdated = DateTimeHelper::currentTimeForDb(); }
/** * Returns the field's input HTML. * * @param string $name * @param mixed $elements * @return string */ public function getInputHtml($name, $elements) { $id = rtrim(preg_replace('/[\\[\\]]+/', '-', $name), '-') . '-' . StringHelper::UUID(); if (!$elements instanceof RelationFieldData) { $elements = new RelationFieldData(); } $criteria = array('status' => null); if (!empty($this->element->id)) { $criteria['id'] = 'not ' . $this->element->id; } if ($this->allowMultipleSources) { $sources = $this->getSettings()->sources; } else { $sources = array($this->getSettings()->source); } return craft()->templates->render('_includes/forms/elementSelect', array('jsClass' => $this->inputJsClass, 'elementType' => new ElementTypeVariable($this->getElementType()), 'id' => $id, 'name' => $name, 'elements' => $elements->all, 'sources' => $sources, 'criteria' => $criteria, 'limit' => $this->allowLimit ? $this->getSettings()->limit : null, 'addButtonLabel' => $this->getAddButtonLabel())); }
/** * Returns a unique indexing session id. * * @return string */ public function getIndexingSessionId() { return StringHelper::UUID(); }