From 07e28ec3a2a09a2ba373744010876ca400145560 Mon Sep 17 00:00:00 2001 From: Vlad Ghita Date: Fri, 22 Jun 2012 14:26:20 +0300 Subject: [PATCH] Release 1.0 --- README.markdown | 38 +++++++ extension.driver.php | 18 ++++ extension.meta.xml | 35 +++++++ fields/field.multilingual_url.php | 165 ++++++++++++++++++++++++++++++ licence | 19 ++++ 5 files changed, 275 insertions(+) create mode 100644 README.markdown create mode 100644 extension.driver.php create mode 100644 extension.meta.xml create mode 100644 fields/field.multilingual_url.php create mode 100644 licence diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..0821f11 --- /dev/null +++ b/README.markdown @@ -0,0 +1,38 @@ +Multilingual Entry URL +====================== + +The multilingual version of the entry url field. + + +## 1 About ## + +When adding this field to a section, the following options are available to you: + +* **Anchor Label** is the text used for the hyperlink in the backend +* **Anchor URL** is the URL of your entry view page on the frontend. An `...` nodeset is provided from which you can grab field values, just as you would from a datasource. For example: + + /members/profile/{entry/name/@handle}/ + +* **For `Multilingual Text`**, you can use `$language_code` (without `{}`) as a placeholder for language codes. It will be replaced for each language on URL generation.
+Let's say my `Articles` Section with a `Multilingual text` field called `Title`. Given an `Articles` Page with an URL param pointing to `Title`, an expression like this must be used: + + /articles/{//title/@*[name() = concat('handle-', $language_code)]}/ --> make sure you know the XML output of Multilingual Text + +* **Open links in a new window** enforces the hyperlink to spawn a new tab/window +* **Hide this field on publish page** hides the hyperlink in the entry edit form + + + +### Note about compatibility ### + +Currently the URL is generated this way: + + /__LANGUAGE-CODE__/URL + + + +## 2 Installation ## + +1. Upload the 'multilingual_entry_url' folder in this archive to your Symphony 'extensions' folder. +2. Enable it by selecting the "Field: Multilingual Entry URL", choose Enable from the with-selected menu, then click Apply. +3. The field will be available in the list when creating a Section. diff --git a/extension.driver.php b/extension.driver.php new file mode 100644 index 0000000..f3acbb3 --- /dev/null +++ b/extension.driver.php @@ -0,0 +1,18 @@ +Symphony Error

You cannot directly access this file

'); + + + + require_once(EXTENSIONS.'/url_field/extension.driver.php'); + + + + class Extension_Multilingual_URL_Field extends Extension_URL_Field + { + public function __construct(){ + parent::__construct(); + + $this->field_table = 'tbl_fields_multilingual_url'; + } + } diff --git a/extension.meta.xml b/extension.meta.xml new file mode 100644 index 0000000..15f180b --- /dev/null +++ b/extension.meta.xml @@ -0,0 +1,35 @@ + + + + + Field: Multilingual URL + + The multilingual version of the URL field. + + https://github.com/vlad-ghita/multilingual_url_field + + + Field Types + Multilingual + + + + + Vlad Ghita + vlad_micutul@yahoo.com + http://www.xanderadvertising.com + + + + + https://github.com/vlad-ghita/url_field + https://github.com/vlad-ghita/multilingual_entry_url + + + + + + + diff --git a/fields/field.multilingual_url.php b/fields/field.multilingual_url.php new file mode 100644 index 0000000..abe9760 --- /dev/null +++ b/fields/field.multilingual_url.php @@ -0,0 +1,165 @@ +Symphony Error

You cannot directly access this file

'); + + + + require_once(EXTENSIONS.'/url_field/fields/field.url.php'); + require_once(EXTENSIONS.'/frontend_localisation/lib/class.FLang.php'); + + + + class FieldMultilingual_URL extends FieldURL + { + + /*------------------------------------------------------------------------------------------------*/ + /* Definition */ + /*------------------------------------------------------------------------------------------------*/ + + public function __construct(){ + parent::__construct(); + + $this->_name = 'Multilingual URL'; + $this->field_types = array('multilingual_entry_url'); + } + + + + /*------------------------------------------------------------------------------------------------*/ + /* Publish */ + /*------------------------------------------------------------------------------------------------*/ + + public function displayPublishPanel(XMLElement &$wrapper, $data = null, $flagWithError = null, $prefix = null, $postfix = null){ + parent::displayPublishPanel($wrapper, $data, $flagWithError, $prefix, $postfix); + + $wrapper->setAttribute('class', $wrapper->getAttribute('class').' field-url'); + } + + + + /*------------------------------------------------------------------------------------------------*/ + /* Output */ + /*------------------------------------------------------------------------------------------------*/ + + public function appendFormattedElement(XMLElement &$wrapper, $data, $encode = false, $mode = null, $entry_id = null) { + if(!is_array($data) || empty($data) || is_null($data['value'])) return; + + $result = new XMLElement($this->get('element_name')); + $result->setAttribute('type',$data['url_type']); + + switch( $data['url_type'] ){ + case 'external': + $result->setValue($data['value']); + break; + + case 'internal': + $lc = FLang::getLangCode(); + $result->setAttribute('id',$data['value']); + $related_value = $this->findRelatedValues(array($data['value']), $lc); + $result->setValue($related_value[0]['value']); + break; + } + + $wrapper->appendChild($result); + } + + + + /*------------------------------------------------------------------------------------------------*/ + /* Utilities */ + /*------------------------------------------------------------------------------------------------*/ + + public function findRelatedValues(array $relation_id = array(), $lc = null){ + // 1. Get the field instances from the SBL's related_field_id's + // FieldManager->fetch doesn't take an array of ID's (unlike other managers) + // so instead we'll instead build a custom where to emulate the same result + // We also cache the result of this where to prevent subsequent calls to this + // field repeating the same query. + $where = ' AND id IN ('.implode(',', $this->get('related_field_id')).') '; + $fields = FieldManager::fetch(null, null, 'ASC', 'sortorder', null, null, $where); + if( !is_array($fields) ){ + $fields = array($fields); + } + + if( empty($fields) ) return array(); + + // 2. Find all the provided `relation_id`'s related section + // We also cache the result using the `relation_id` as identifier + // to prevent unnecessary queries + $relation_id = array_filter($relation_id); + if( empty($relation_id) ) return array(); + + + $relation_ids = Symphony::Database()->fetch(sprintf(" + SELECT e.id, e.section_id, s.name, s.handle + FROM `tbl_entries` AS `e` + LEFT JOIN `tbl_sections` AS `s` ON (s.id = e.section_id) + WHERE e.id IN (%s) + ORDER BY `e`.creation_date DESC + ", + implode(',', $relation_id) + )); + + // 3. Group the `relation_id`'s by section_id + $section_ids = array(); + $section_info = array(); + foreach( $relation_ids as $relation_information ){ + $section_ids[$relation_information['section_id']][] = $relation_information['id']; + + if( !array_key_exists($relation_information['section_id'], $section_info) ){ + $section_info[$relation_information['section_id']] = array( + 'name' => $relation_information['name'], + 'handle' => $relation_information['handle'] + ); + } + } + + if( is_null($lc) ) + $lc = Lang::get(); + + if( !FLang::validateLangCode($lc) ) + $lc = FLang::getLangCode(); + + // 4. Foreach Group, use the EntryManager to fetch the entry information + // using the schema option to only return data for the related field + $relation_data = array(); + foreach( $section_ids as $section_id => $entry_data ){ + $schema = array(); + // Get schema + foreach( $fields as $field ){ + if( $field->get('parent_section') == $section_id ){ + $schema = array($field->get('element_name')); + break; + } + } + + EntryManager::setFetchSorting('date', 'DESC'); + $entries = EntryManager::fetch(array_values($entry_data), $section_id, null, null, null, null, false, true, $schema); + + // 5. Loop over the Entries fetching URL data + foreach( $entries as $entry ){ + $url_data = $entry->getData($field->get('id')); + + $relation_data[] = array( + 'id' => $entry->get('id'), + 'section_handle' => $section_info[$section_id]['handle'], + 'section_name' => $section_info[$section_id]['name'], + 'value' => $url_data["value-$lc"], + 'label' => $url_data["label-$lc"] + ); + } + } + + // 6. Return the resulting array containing the id, section_handle, section_name and value + return $relation_data; + } + + + + /*------------------------------------------------------------------------------------------------*/ + /* Field schema */ + /*------------------------------------------------------------------------------------------------*/ + + public function appendFieldSchema($f){} + + } diff --git a/licence b/licence new file mode 100644 index 0000000..ee3968e --- /dev/null +++ b/licence @@ -0,0 +1,19 @@ +Copyright 2012 Xander Group(www.xanderadvertising.ro) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.