diff --git a/README.md b/README.md index ed4db46..8929d8d 100644 --- a/README.md +++ b/README.md @@ -31,4 +31,8 @@ Capture groups are just used by the standard $1, $2, ect. within your "Redirect **Redirect To:** "shop$1" -*Note, we do not include the "/" because it will be part of the capture group* \ No newline at end of file +*Note, we do not include the "/" because it will be part of the capture group* + +#### Import by CSV +Multiple records can be imported by generating a CSV of redirects. +See 'example.csv' for a starting point. \ No newline at end of file diff --git a/example.csv b/example.csv new file mode 100644 index 0000000..46467e7 --- /dev/null +++ b/example.csv @@ -0,0 +1,2 @@ +uri-to-match,/location-to-redirect-to,302 +another-uri-to-match,/another-location-to-redirect-to,301 \ No newline at end of file diff --git a/redirectmanager/RedirectManagerPlugin.php b/redirectmanager/RedirectManagerPlugin.php index 95b4ab5..defbf6f 100755 --- a/redirectmanager/RedirectManagerPlugin.php +++ b/redirectmanager/RedirectManagerPlugin.php @@ -59,7 +59,9 @@ public function registerCpRoutes() { return array( 'redirectmanager\/new' => 'redirectmanager/_edit', - 'redirectmanager\/(?P\d+)' => 'redirectmanager/_edit' + 'redirectmanager\/(?P\d+)' => 'redirectmanager/_edit', + 'redirectmanager\/import' => 'redirectmanager/_import', + 'redirectmanager\/import/report' => 'redirectmanager/_import-report', ); } public function onAfterInstall() diff --git a/redirectmanager/controllers/RedirectManagerController.php b/redirectmanager/controllers/RedirectManagerController.php index 0e0742f..3d83c9e 100755 --- a/redirectmanager/controllers/RedirectManagerController.php +++ b/redirectmanager/controllers/RedirectManagerController.php @@ -26,15 +26,40 @@ public function actionSaveRedirect() } } + public function actionImportRedirects() + { + $this->requirePostRequest(); + + $csvData = craft()->request->getPost('redirectRecord')['csv']; + + try { + $arrRedirects = craft()->redirectManager->processCSV($csvData); + + $arrResult = craft()->redirectManager->saveRedirects($arrRedirects); + + // Save the output to the session + craft()->httpSession->add('redirectmanager.result', $arrResult); + + } catch (Exception $e) { + + craft()->userSession->setError(Craft::t($e->getMessage())); + + return $this->redirect('redirectmanager/import'); + } + + return $this->redirect('redirectmanager/import/report'); + + } + public function actionDeleteRedirect() { - + $this->requirePostRequest(); $this->requireAjaxRequest(); - + $id = craft()->request->getRequiredPost('id'); craft()->redirectManager->deleteRedirectById($id); - + $this->returnJson(array('success' => true)); } } diff --git a/redirectmanager/services/RedirectManagerService.php b/redirectmanager/services/RedirectManagerService.php index 7842331..40e41d7 100644 --- a/redirectmanager/services/RedirectManagerService.php +++ b/redirectmanager/services/RedirectManagerService.php @@ -57,6 +57,20 @@ public function processRedirect($uri) return (isset($redirectLocation)) ? array("url" => ( strpos($record['location'], "http") === 0 ) ? $redirectLocation : UrlHelper::getSiteUrl($redirectLocation), "type" => $record['type']) : false; } + public function processCSV($csv) + { + if ($csv == '') { + throw new Exception('The CSV data appears to be missing.'); + } + // Replace newlines with commas + $results = preg_replace("/[\n\r]+/", ',', $csv); + + // Parse the CSV file and split into an associative array + $results = array_chunk(str_getcsv($results, ','), 3); + + return $results; + } + public function newRedirect($attributes = array()) { $model = new RedirectManagerModel(); @@ -101,12 +115,71 @@ public function saveRedirect(RedirectManagerModel &$model) } } + public function saveRedirects($arrRedirects) + { + // Loop through and save (track the outcome for each record) + $arrResult = [ + 'success' => [], + 'failed' => [] + ]; + + foreach ($arrRedirects as $redirect) { + + $model = $this->newRedirect([ + 'uri' => $redirect[0], + 'location' => $redirect[1], + 'type' => $redirect[2] + ]); + + if ($this->saveRedirect($model)) { + $arrResult['success'][] = $redirect; + } else { + if ($this->recordExistsAndShouldOverwrite($model)) { + + $record = $this->findByAttributes(['uri' => $model->getAttribute('uri')]); + + $model->setAttribute('id', $record->getAttribute('id')); + + if ($this->saveRedirect($model)) { + $arrResult['success'][] = $redirect; + } else { + $redirect['failureMessageArray'] = $model->getErrors(); + $arrResult['failed'][] = $redirect; + } + } else { + $redirect['failureMessageArray'] = $model->getErrors(); + $arrResult['failed'][] = $redirect; + } + } + + + } + + return $arrResult; + + } + public function deleteRedirectById($id) { return $this->redirectRecord->deleteByPk($id); } - private function _processRegexMatch($uriToMatch, $uri) + public function findByAttributes($attributes,$condition='',$params=array()) + { + return $this->redirectRecord->findByAttributes($attributes, $condition, $params); + } + + /** + * @param $model + * + * @return bool + */ + public function recordExistsAndShouldOverwrite($model) + { + return ($model->getError('uri') != null && craft()->request->getPost('redirectRecord')['overwrite']); + } + + private function _processRegexMatch($uriToMatch, $uri) { preg_match("/^#(.+)#$/", $uriToMatch, $matches); // return ($matches[1] == $uri) ; diff --git a/redirectmanager/templates/_import-report.html b/redirectmanager/templates/_import-report.html new file mode 100644 index 0000000..cac4119 --- /dev/null +++ b/redirectmanager/templates/_import-report.html @@ -0,0 +1,118 @@ +{% extends "_layouts/cp" %} +{% import "_includes/forms" as forms %} + +{% set redirectId = null %} +{% set redirectRecord = (redirectId) ? craft.redirectManager.getRedirectById(redirectId) : null %} + +{% if redirectId and not redirectRecord %} + {% exit 404 %} +{% endif %} + +{% set title = "Import Report"|t %} +{% set crumbs = [ + { label: "Redirect Manager"|t, url: url('redirectmanager') }, + { label: "Importer"|t, url: url('redirectmanager/import') } +] %} + + + +{% set content %} + + {% set arrSuccess = craft.redirectManager.getImportResultSuccess %} + {% set arrFailed = craft.redirectManager.getImportResultFailed %} + + {% if arrSuccess | length %} +

Redirects imported successfully

+ + + + + + + + + + {% for result in arrSuccess %} + + + + + + + + {% endfor %} +
URILocationType 
{{ result[0] }}{{ result[1] }}{{ result[2] }} 
+ {% endif %} + {% if arrFailed | length %} +

Redirects failed

+ + + + + + + + + + {% for result in arrFailed %} + + + + + + + + {% endfor %} +
URILocationTypeReason
{{ result[0] }}{{ result[1] }}{{ result[2] }} + {% for block in result['failureMessageArray'] %} + {%for error in block|keys %} + {% if error == 'uri' %} + The URI already exists + {% endif %} + {% endfor %} + {% endfor %} +
+ {% endif %} + +{% endset %} diff --git a/redirectmanager/templates/_import.html b/redirectmanager/templates/_import.html new file mode 100644 index 0000000..21d2bcf --- /dev/null +++ b/redirectmanager/templates/_import.html @@ -0,0 +1,62 @@ +{% extends "_layouts/cp" %} +{% import "_includes/forms" as forms %} + +{% set redirectId = null %} +{% set redirectRecord = (redirectId) ? craft.redirectManager.getRedirectById(redirectId) : null %} + +{% if redirectId and not redirectRecord %} + {% exit 404 %} +{% endif %} + +{% set title = "Import Redirects"|t %} +{% set crumbs = [ + { label: "Redirect Manager"|t, url: url('redirectmanager') } +] %} + + + +{% set content %} + +
+

Instructions

+

+ Your CSV data should be in the following format:
+

+
uri-to-match,/location-to-redirect-to,redirect type (301 or 302)
+another-uri-to-match,/another-location-to-redirect-to,301
+        
+
+ +
+ {{ getCsrfInput() }} + + + +

+ {{ forms.textareaField({ + label: 'CSV Data'|t, + required: true, + name: 'redirectRecord[csv]', + value: redirectRecord ? redirectRecord.csv : null, + errors: redirectRecord ? redirectRecord.errors('csv') : null, + instructions: "Paste your CSV data here", + rows: 20, + }) }} +

+

+ {{ forms.lightswitchField({ + label: 'Replace Matching Records?'|t, + required: true, + name: 'redirectRecord[overwrite]', + value: redirectRecord ? redirectRecord.overwrite : null, + errors: redirectRecord ? redirectRecord.errors('overwrite') : null, + instructions: "Do you want to overwrite an existing record if the URI matches?", + }) }} +

+ +
+ +
+
+ +{% endset %} diff --git a/redirectmanager/templates/index.html b/redirectmanager/templates/index.html index fef14ae..0a4772d 100644 --- a/redirectmanager/templates/index.html +++ b/redirectmanager/templates/index.html @@ -37,6 +37,7 @@ {% endset %} diff --git a/redirectmanager/variables/RedirectManagerVariable.php b/redirectmanager/variables/RedirectManagerVariable.php index 8253677..0d9babb 100644 --- a/redirectmanager/variables/RedirectManagerVariable.php +++ b/redirectmanager/variables/RedirectManagerVariable.php @@ -14,5 +14,14 @@ public function getRedirectById($id) { return craft()->redirectManager->getRedirectById($id); } - + + public function getImportResultSuccess() + { + return craft()->httpSession->get('redirectmanager.result')['success']; + } + + public function getImportResultFailed() + { + return craft()->httpSession->get('redirectmanager.result')['failed']; + } }