public function getFeed($url, $primaryElement, $returnAttr = false) { if (false === ($raw_content = craft()->feedMe_feed->getRawData($url))) { craft()->userSession->setError(Craft::t('Unable to parse Feed URL.')); FeedMePlugin::log('Unable to parse Feed URL.', LogLevel::Error, true); return false; } // Perform cleanup on raw data first //$raw_content = preg_replace("/[\r\n]+/", " ", $raw_content); //$xml = stripslashes($raw_content); //$xml = utf8_encode($xml); //$xml = StringHelper::convertToUTF8($xml); // Parse the XML string $xml_array = $this->parseXML($raw_content); // Convert it to an array $xml_array = $this->elementArray($xml_array, true, $returnAttr); // Look for and return only the items for primary element $xml_array = craft()->feedMe_feed->findPrimaryElement($primaryElement, $xml_array); if (!is_array($xml_array)) { craft()->userSession->setError(Craft::t('Invalid XML.')); FeedMePlugin::log('Invalid XML.', LogLevel::Error, true); return false; } return $xml_array; }
public function getTotalSteps() { // Get settings $settings = $this->getSettings(); // Get the Feed $this->_feed = $settings->feed; // There are also a few once-off things we can do for this feed to assist with processing. $this->_feedSettings = craft()->feedMe->setupForImport($this->_feed); // Get the data for the mapping screen, based on the URL provided $this->_feedData = craft()->feedMe_feed->getFeed($this->_feed->feedType, $this->_feed->feedUrl, $this->_feed->primaryElement); if (!$this->_feedData) { FeedMePlugin::log($this->_feed->name . ': FeedMeError', LogLevel::Error, true); return false; } // Chunk the feed data into chunks of 100 - optimises mapping process by not calling service each step $this->_chunkedFeedData = array_chunk($this->_feedData, 100); // Delete all the entry caches craft()->templateCache->deleteCachesByElementType('Entry'); // Create a backup before we do anything to the DB if ($this->_feed->backup) { $backup = craft()->db->backup(); } // Take a step for every row return count($this->_chunkedFeedData); }
public function log($settings, $errors, $level) { // Firstly, store in plugin log file (use $level to control log level) FeedMePlugin::log(print_r($errors, true), $level, true); // Save this log to the DB as well if (isset($settings->attributes['logsId'])) { $logsId = $settings->logsId; if (FeedMe_LogsRecord::model()->findById($logsId)) { $log = new FeedMe_LogRecord(); $log->logsId = $logsId; $log->errors = print_r($errors, true); $log->save(false); } } }
public function getFeed($url, $primaryElement) { if (false === ($raw_content = craft()->feedMe_feed->getRawData($url))) { craft()->userSession->setError(Craft::t('Unable to parse Feed URL.')); FeedMePlugin::log('Unable to parse Feed URL.', LogLevel::Error, true); return false; } // Parse the JSON string - using Yii's built-in cleanup $json_array = JsonHelper::decode($raw_content, true); // Look for and return only the items for primary element $json_array = craft()->feedMe_feed->findPrimaryElement($primaryElement, $json_array); if (!is_array($json_array)) { $error = 'Invalid JSON - ' . $this->getJsonError(); craft()->userSession->setError(Craft::t($error)); FeedMePlugin::log($error, LogLevel::Error, true); return false; } return $json_array; }
public function getRawData($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($curl); if (!$response) { FeedMePlugin::log(curl_error($curl), LogLevel::Error, true); return false; } curl_close($curl); return $response; }
public function deleteLeftoverEntries($settings, $feed, $processedEntries, $result) { if ($feed['duplicateHandle'] == FeedMe_Duplicate::Delete && $result['result']) { $deleteIds = array_diff($settings['existingEntries'], $processedEntries); $criteria = craft()->feedMe_entry->setCriteria($feed); $criteria->id = $deleteIds; $entriesToDelete = $criteria->find(); try { if ($entriesToDelete) { if (!craft()->entries->deleteEntry($entriesToDelete)) { FeedMePlugin::log('FeedMeError - Something went wrong while deleting entries.', LogLevel::Error, true); } else { FeedMePlugin::log($feed->name . ': The following entries have been deleted: ' . print_r($deleteIds, true) . '.', LogLevel::Error, true); } } } catch (\Exception $e) { FeedMePlugin::log($feed->name . ': FeedMeError: ' . $e->getMessage() . '.', LogLevel::Error, true); } } }
public function importSingleNode($node, $feed, $settings) { $canSaveEntry = true; $existingEntry = false; $fieldData = array(); $entry = array(); $fields = $settings['fields']; // // Lets get started! // $criteria = craft()->feedMe_entry->setCriteria($feed); // Start looping through all the mapped fields - grab their data from the feed node foreach ($fields as $itemNode => $handle) { // Fetch the value for the field from the feed node. Deep-search. $data = craft()->feedMe_feed->getValueForNode($itemNode, $node); // While we're in the loop, lets check for unique data to match existing entries on. if (isset($feed['fieldUnique'][$itemNode]) && intval($feed['fieldUnique'][$itemNode]) == 1 && !empty($data)) { $criteria->{$handle} = DbHelper::escapeParam($data); } // // Each field needs special processing, sort that out here // try { // Grab the field's content - formatted specifically for it $content = craft()->feedMe_fields->prepForFieldType($data, $handle); // The first key of $content will always be the field handle - grab that to create our field data. $fieldHandle = array_keys($content)[0]; // Then, we check if we've already got any partial content for the field. Most commongly, this is // the case for Matrix and Table fields, but also likely other Third-Party fields. So its important to // combine values, rather than overwriting or omitting as each feed node contains just part of the data. if (array_key_exists($fieldHandle, $fieldData) && is_array($fieldData[$fieldHandle])) { $fieldData[$fieldHandle] = array_replace_recursive($fieldData[$fieldHandle], $content[$fieldHandle]); } else { $fieldData[$fieldHandle] = $content[$fieldHandle]; } } catch (\Exception $e) { FeedMePlugin::log($feed->name . ': FeedMeError: ' . $e->getMessage() . '.', LogLevel::Error, true); return false; } } // Any post-processing on our nice collection of entry-ready data. craft()->feedMe_fields->postForFieldType($fieldData); $existingEntry = $criteria->first(); // // Check for Add/Update/Delete for existing entries // // If there's an existing matching entry if ($existingEntry && $feed['duplicateHandle'] != FeedMe_Duplicate::Delete) { // If we're updating if ($feed['duplicateHandle'] == FeedMe_Duplicate::Update) { // Fill new EntryModel with match $entry = $existingEntry; // If we're adding, make sure not to overwrite existing entry } else { if ($feed['duplicateHandle'] == FeedMe_Duplicate::Add) { $canSaveEntry = false; } } } else { // Prepare a new EntryModel (for this section and entrytype) $entry = craft()->feedMe_entry->setModel($feed); } // // // if ($canSaveEntry && $entry) { // Prepare Element model (the default stuff) $entry = craft()->feedMe_entry->prepForElementModel($fieldData, $entry); // Set our data for this EntryModel (our mapped data) $entry->setContentFromPost($fieldData); //echo '<pre>'; //print_r($fieldData); //echo '</pre>'; try { // Save the entry! if (!craft()->entries->saveEntry($entry)) { FeedMePlugin::log($feed->name . ': ' . json_encode($entry->getErrors()), LogLevel::Error, true); return false; } else { // Successfully saved/added entry if ($feed['duplicateHandle'] == FeedMe_Duplicate::Update) { FeedMePlugin::log($feed->name . ': Entry successfully updated: ' . $entry->id, LogLevel::Info, true); } else { FeedMePlugin::log($feed->name . ': Entry successfully added: ' . $entry->id, LogLevel::Info, true); } return true; } } catch (\Exception $e) { FeedMePlugin::log($feed->name . ': Entry FeedMeError: ' . $e->getMessage() . '.', LogLevel::Error, true); return false; } } }
public function actionSendSupportRequest() { $this->requirePostRequest(); craft()->config->maxPowerCaptain(); $success = false; $errors = array(); $zipFile = null; $tempFolder = null; $getHelpModel = new FeedMe_GetHelpModel(); $getHelpModel->fromEmail = craft()->request->getPost('fromEmail'); $getHelpModel->feedIssue = craft()->request->getPost('feedIssue'); $getHelpModel->message = trim(craft()->request->getPost('message')); $getHelpModel->attachLogs = (bool) craft()->request->getPost('attachLogs'); $getHelpModel->attachSettings = (bool) craft()->request->getPost('attachSettings'); $getHelpModel->attachFeed = (bool) craft()->request->getPost('attachFeed'); $getHelpModel->attachFields = (bool) craft()->request->getPost('attachFields'); $getHelpModel->attachment = UploadedFile::getInstanceByName('attachAdditionalFile'); if ($getHelpModel->validate()) { $plugin = craft()->plugins->getPlugin('feedMe'); $feed = craft()->feedMe_feeds->getFeedById($getHelpModel->feedIssue); // Add some extra info about this install $message = $getHelpModel->message . "\n\n" . "------------------------------\n\n" . 'Craft ' . craft()->getEditionName() . ' ' . craft()->getVersion() . '.' . craft()->getBuild() . "\n\n" . 'Feed Me ' . $plugin->getVersion(); try { $zipFile = $this->_createZip(); $tempFolder = craft()->path->getTempPath() . StringHelper::UUID() . '/'; if (!IOHelper::folderExists($tempFolder)) { IOHelper::createFolder($tempFolder); } // // Attached just the Feed Me log // if ($getHelpModel->attachLogs) { if (IOHelper::folderExists(craft()->path->getLogPath())) { $logFolderContents = IOHelper::getFolderContents(craft()->path->getLogPath()); foreach ($logFolderContents as $file) { // Just grab the Feed Me log if (IOHelper::fileExists($file) && basename($file) == 'feedme.log') { Zip::add($zipFile, $file, craft()->path->getStoragePath()); } } } } // // Backup our feed settings // if ($getHelpModel->attachSettings) { if (IOHelper::folderExists(craft()->path->getDbBackupPath())) { $backup = craft()->path->getDbBackupPath() . StringHelper::toLowerCase('feedme_' . gmdate('ymd_His') . '.sql'); $feedInfo = $this->_prepareSqlFeedSettings($getHelpModel->feedIssue); IOHelper::writeToFile($backup, $feedInfo . PHP_EOL, true, true); Zip::add($zipFile, $backup, craft()->path->getStoragePath()); } } // // Save the contents of the feed // if ($getHelpModel->attachFeed) { $feedData = craft()->feedMe_feed->getRawData($feed->feedUrl); $tempFile = $tempFolder . 'feed.' . StringHelper::toLowerCase($feed->feedType); IOHelper::writeToFile($tempFile, $feedData . PHP_EOL, true, true); if (IOHelper::fileExists($tempFile)) { Zip::add($zipFile, $tempFile, $tempFolder); } } // // Get some information about the fields we're mapping to - handy to know // if ($getHelpModel->attachFields) { $fieldInfo = array(); foreach ($feed->fieldMapping as $feedHandle => $fieldHandle) { $field = craft()->fields->getFieldByHandle($fieldHandle); if ($field) { $fieldInfo[] = $this->_prepareExportField($field); } } // Support PHP <5.4, JSON_PRETTY_PRINT = 128, JSON_NUMERIC_CHECK = 32 $json = json_encode($fieldInfo, 128 | 32); $tempFile = $tempFolder . 'fields.json'; IOHelper::writeToFile($tempFile, $json . PHP_EOL, true, true); if (IOHelper::fileExists($tempFile)) { Zip::add($zipFile, $tempFile, $tempFolder); } } // // Add in any additional attachments // if ($getHelpModel->attachment) { $tempFile = $tempFolder . $getHelpModel->attachment->getName(); $getHelpModel->attachment->saveAs($tempFile); // Make sure it actually saved. if (IOHelper::fileExists($tempFile)) { Zip::add($zipFile, $tempFile, $tempFolder); } } } catch (\Exception $e) { FeedMePlugin::log('Tried to attach debug logs to a support request and something went horribly wrong: ' . $e->getMessage(), LogLevel::Warning, true); } $email = new EmailModel(); $email->fromEmail = $getHelpModel->fromEmail; $email->toEmail = "*****@*****.**"; $email->subject = "Feed Me Support"; $email->body = $message; if ($zipFile) { $email->addAttachment($zipFile, 'FeedMeSupportAttachment.zip', 'base64', 'application/zip'); } $result = craft()->email->sendEmail($email); if ($result) { if ($zipFile) { if (IOHelper::fileExists($zipFile)) { IOHelper::deleteFile($zipFile); } } if ($tempFolder) { IOHelper::clearFolder($tempFolder); IOHelper::deleteFolder($tempFolder); } $success = true; } else { $errors = array('Support' => array('Unable to contact support. Please try again soon.')); } } else { $errors = $getHelpModel->getErrors(); } $this->returnJson(array('success' => $success, 'errors' => $errors)); }
public function importSingleNode($node, $feed, $settings) { $canSaveEntry = true; $existingEntry = false; $fieldData = array(); $entry = array(); $fields = $settings['fields']; // // Lets get started! // $criteria = craft()->feedMe_entry->setCriteria($feed); // Start looping through all the mapped fields - grab their data from the feed node foreach ($fields as $itemNode => &$destination) { // Fetch the value for the field from the feed node. Deep-search. $data = craft()->feedMe_feed->getValueForNode($itemNode, $node); // While we're in the loop, lets check for unique data to match existing entries on. if (isset($feed['fieldUnique'][$itemNode]) && intval($feed['fieldUnique'][$itemNode]) == 1 && !empty($data)) { $criteria->{$destination} = DbHelper::escapeParam($data); } // // Each field needs special processing, sort that out here // try { // The field handle needs to be modified in some cases (Matrix and Table). Here, we don't override // the original handle for future iterations. We use the original handle to identify Matrix/Table fields. $handle = $destination; // Grab the field's content - formatted specifically for it $content = craft()->feedMe_fields->prepForFieldType($data, $handle); // Check to see if this is a Matrix field - need to merge any other fields mapped elsewhere in the feed // along with fields we've processed already. Involved due to multiple blocks can be defined at once. if (substr($destination, 0, 10) == '__matrix__') { $content = craft()->feedMe_fields->handleMatrixData($fieldData, $handle, $content); } // And another special case for Table data if (substr($destination, 0, 9) == '__table__') { $content = craft()->feedMe_fields->handleTableData($fieldData, $handle, $content); } // And another special case for SuperTable data if (substr($destination, 0, 14) == '__supertable__') { $content = craft()->feedMe_fields->handleSuperTableData($fieldData, $handle, $content); } // Finally - we have our mapped data, formatted for the particular field as required $fieldData[$handle] = $content; } catch (\Exception $e) { FeedMePlugin::log($feed->name . ': FeedMeError: ' . $e->getMessage() . '.', LogLevel::Error, true); return false; } } $existingEntry = $criteria->first(); // // Check for Add/Update/Delete for existing entries // // If there's an existing matching entry if ($existingEntry && $feed['duplicateHandle'] != FeedMe_Duplicate::Delete) { // If we're updating if ($feed['duplicateHandle'] == FeedMe_Duplicate::Update) { // Fill new EntryModel with match $entry = $existingEntry; // If we're adding, make sure not to overwrite existing entry } else { if ($feed['duplicateHandle'] == FeedMe_Duplicate::Add) { $canSaveEntry = false; } } } else { // Prepare a new EntryModel (for this section and entrytype) $entry = craft()->feedMe_entry->setModel($feed); } // // // if ($canSaveEntry && $entry) { // Prepare Element model (the default stuff) $entry = craft()->feedMe_entry->prepForElementModel($fieldData, $entry); // Set our data for this EntryModel (our mapped data) $entry->setContentFromPost($fieldData); //echo '<pre>'; //print_r($entry->title); //echo '</pre>'; try { // Save the entry! if (!craft()->entries->saveEntry($entry)) { FeedMePlugin::log($feed->name . ': ' . json_encode($entry->getErrors()), LogLevel::Error, true); return false; } else { // Successfully saved/added entry if ($feed['duplicateHandle'] == FeedMe_Duplicate::Update) { FeedMePlugin::log($feed->name . ': Entry successfully updated: ' . $entry->id, LogLevel::Info, true); } else { FeedMePlugin::log($feed->name . ': Entry successfully added: ' . $entry->id, LogLevel::Info, true); } return true; } } catch (\Exception $e) { FeedMePlugin::log($feed->name . ': Entry FeedMeError: ' . $e->getMessage() . '.', LogLevel::Error, true); return false; } } }