From 266d6b7e7b41288dee5d07832c0fbc5eef358cc0 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer <reinhold@kainhofer.com> Date: Sat, 22 Nov 2014 22:18:27 +0100 Subject: [PATCH] RegExp V1.0: Initial version of the RegExp vmshipmentrules plugin that provides five regexp-matching/replacing functions --- plugins/regexp/Makefile | 19 ++++ plugins/regexp/index.html | 0 .../en-GB.plg_vmshipmentrules_regexp.ini | 8 ++ .../en-GB.plg_vmshipmentrules_regexp.sys.ini | 6 ++ plugins/regexp/language/en-GB/index.html | 1 + plugins/regexp/language/index.html | 1 + plugins/regexp/regexp.php | 93 ++++++++++++++++++ plugins/regexp/regexp.script.php | 88 +++++++++++++++++ plugins/regexp/regexp.xml | 27 +++++ ..._opentools_vmshipmentrules_regexp_v1.0.zip | Bin 0 -> 4853 bytes 10 files changed, 243 insertions(+) create mode 100644 plugins/regexp/Makefile create mode 100644 plugins/regexp/index.html create mode 100644 plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.ini create mode 100644 plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.sys.ini create mode 100644 plugins/regexp/language/en-GB/index.html create mode 100644 plugins/regexp/language/index.html create mode 100644 plugins/regexp/regexp.php create mode 100644 plugins/regexp/regexp.script.php create mode 100644 plugins/regexp/regexp.xml create mode 100644 plugins/regexp/releases/plg_opentools_vmshipmentrules_regexp_v1.0.zip diff --git a/plugins/regexp/Makefile b/plugins/regexp/Makefile new file mode 100644 index 0000000..38d4f19 --- /dev/null +++ b/plugins/regexp/Makefile @@ -0,0 +1,19 @@ +BASE=regexp +PLUGINTYPE=vmshipmentrules +ZIPBASE=opentools_vmshipmentrules +VERSION=1.0 + +PLUGINFILES=$(BASE).php $(BASE).script.php $(BASE).xml index.html + +TRANSLATIONS=$(call wildcard,language/en*/*.plg_$(PLUGINTYPE)_$(BASE).*ini) +INDEXFILES=language/index.html $(call wildcard,language/**/index.html) +ZIPFILE=plg_$(ZIPBASE)_$(BASE)_v$(VERSION).zip + +all: zip + +zip: $(PLUGINFILES) $(TRANSLATIONS) $(ADVANCEDFILES) $(INDEXFILES) + @echo "Packing all files into distribution file $(ZIPFILE):" + @zip -r $(ZIPFILE) $(PLUGINFILES) $(TRANSLATIONS) $(INDEXFILES) + +clean: + rm -f $(ZIPFILE) diff --git a/plugins/regexp/index.html b/plugins/regexp/index.html new file mode 100644 index 0000000..e69de29 diff --git a/plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.ini b/plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.ini new file mode 100644 index 0000000..52f8ee3 --- /dev/null +++ b/plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.ini @@ -0,0 +1,8 @@ +; VM Rule-based Shipping plugin: Extension plugin providing regexp functions +; Copyright (C) 2014 Reinhold Kainhofer, Open Tools. All rights reserved. +; License http://www.gnu.org/licenses/gpl.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM +VMSHIPMENTRULES_REGEXP="VM Shipping by Rules: RegExp functions" +VMSHIPMENTRULES_REGEXP_DESC="This plugin provides functions for regular expression matches to the Shipping by Rules plugin." + +VMSHIPMENT_RULES_REGEXP_ARGS="The function %s needs to be called with %s arguments: %s. <br />Encountered in rule '%s'." \ No newline at end of file diff --git a/plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.sys.ini b/plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.sys.ini new file mode 100644 index 0000000..877988d --- /dev/null +++ b/plugins/regexp/language/en-GB/en-GB.plg_vmshipmentrules_regexp.sys.ini @@ -0,0 +1,6 @@ +; VM Rule-based Shipping plugin: Extension plugin providing regexp functions +; Copyright (C) 2014 Reinhold Kainhofer, Open Tools. All rights reserved. +; License http://www.gnu.org/licenses/gpl.html GNU/GPL +; Note : All ini files need to be saved as UTF-8 - No BOM +VMSHIPMENTRULES_REGEXP="VM Shipping by Rules: RegExp functions" +VMSHIPMENTRULES_REGEXP_DESC="This plugin provides functions for regular expression matches to the Shipping by Rules plugin." diff --git a/plugins/regexp/language/en-GB/index.html b/plugins/regexp/language/en-GB/index.html new file mode 100644 index 0000000..2efb97f --- /dev/null +++ b/plugins/regexp/language/en-GB/index.html @@ -0,0 +1 @@ +<!DOCTYPE html><title></title> diff --git a/plugins/regexp/language/index.html b/plugins/regexp/language/index.html new file mode 100644 index 0000000..2efb97f --- /dev/null +++ b/plugins/regexp/language/index.html @@ -0,0 +1 @@ +<!DOCTYPE html><title></title> diff --git a/plugins/regexp/regexp.php b/plugins/regexp/regexp.php new file mode 100644 index 0000000..0b6d961 --- /dev/null +++ b/plugins/regexp/regexp.php @@ -0,0 +1,93 @@ +<?php + +defined ('_JEXEC') or die('Restricted access'); + +/** + * Plugin providing regexp function for VM Shipping by Rules + * + * @subpackage Plugins - VmShipmentRules + * @copyright Copyright (C) 2014 Reinhold Kainhofer, office@open-tools.net + * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php + * VirtueMart is free software. This version may have been modified pursuant + * to the GNU General Public License, and as distributed it includes or + * is derivative of works licensed under the GNU General Public License or + * other free or open source software licenses. + * See administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details. + * + * http://open-tools.net/ + * + */ +if (!class_exists ('VmPlugin')) { + require(JPATH_VM_PLUGINS . DS . 'vmplugin.php'); +} + +/** This plugin provides the following RegExp-related functions to the shipping by rules plugin: + * - RegExpMatch(pattern, value) - returns whether the value matches the expression (true/false) + * - RegExpMatches(pattern, value) - returns an array of all matches of regexp within the value (array) + * - RegExpReplace(pattern, value) - preforms a regexp replacement on the value, returns the resulting string (string) + * - RegExpSplit(pattern, value) - splits value using the regexp as delimiter, returns array of all substrings (excluding the delimiter) (array) + * - RegExpFilter(pattern, array) - returns all members of the array that match the regexp (array) + */ + +/** Extension plugin for the "Shipping by Rules" shipping plugin for VirtueMart + */ +class plgVmShipmentRulesRegexp extends VmPlugin { + /** Register the regexp functions... */ + function onVmShippingRulesRegisterCustomFunctions() { + return array( + 'RegExpMatch' => array('plgVmShipmentRulesRegexp', 'rules_regexp_match'), + 'RegExpMatches' => array('plgVmShipmentRulesRegexp', 'rules_regexp_matches'), + 'RegExpReplace' => array('plgVmShipmentRulesRegexp', 'rules_regexp_replace'), + 'RegExpSplit' => array('plgVmShipmentRulesRegexp', 'rules_regexp_split'), + 'RegExpFilter' => array('plgVmShipmentRulesRegexp', 'rules_regexp_filter'), + ); + } + + /** RegExpMatch(RegExp, string) => return true/false */ + static function rules_regexp_match($args, $rule) { + if (count($args)<2) { + JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_REGEXP_ARGS', "RegExpMatch", "two", "RegExpMatch(pattern, string)", htmlentities($rule->rulestring)), 'error'); + return false; + } + return preg_match($args[0], $args[1]); + } + + /** RegExpMatches(RegExp, string) => returns an array of all matches of regexp in the given string */ + static function rules_regexp_matches($args, $rule) { + if (count($args)<2) { + JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_REGEXP_ARGS', "RegExpMatches", "two", "RegExpMatches(pattern, string)", htmlentities($rule->rulestring)), 'error'); + return false; + } + preg_match_all($args[0], $args[1], $matches); + return $matches[0]; + } + + /** RegExpReplace(RegExp, string) => preforms a regexp replacement on the value, returns the resulting string */ + static function rules_regexp_replace($args, $rule) { + if (count($args)<3) { + JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_REGEXP_ARGS', "RegExpReplace", "three", "RegExpReplace(pattern, replacement, string)", htmlentities($rule->rulestring)), 'error'); + return false; + } + return preg_replace($args[0], $args[1], $args[2]); + } + + /** RegExpSplit(RegExp, string) => preforms a regexp replacement on the value, returns the resulting string */ + static function rules_regexp_split($args, $rule) { + if (count($args)<2) { + JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_REGEXP_ARGS', "RegExpSplit", "two", "RegExpSplit(pattern, string)", htmlentities($rule->rulestring)), 'error'); + return false; + } + return preg_split($args[0], $args[1]); + } + + /** RegExpFilter(RegExp, array) => returns all entries of the array that match the regexp pattern */ + static function rules_regexp_filter($args, $rule) { + if (count($args)<2) { + JFactory::getApplication()->enqueueMessage(JText::sprintf('VMSHIPMENT_RULES_REGEXP_ARGS', "RegExpFilter", "two", "RegExpFilter(pattern, array)", htmlentities($rule->rulestring)), 'error'); + return false; + } + return preg_grep($args[0], $args[1]); + } +} + +// No closing tag diff --git a/plugins/regexp/regexp.script.php b/plugins/regexp/regexp.script.php new file mode 100644 index 0000000..843e90e --- /dev/null +++ b/plugins/regexp/regexp.script.php @@ -0,0 +1,88 @@ +<?php +defined('_JEXEC') or die('Restricted access'); + +/** + * Installation script for the plugin + * + * @copyright Copyright (C) 2014 Reinhold Kainhofer, office@open-tools.net + * @license GPL v3+, http://www.gnu.org/copyleft/gpl.html + */ + +// Adjust the class name. It has to be of the form: +// plgVmShipmentRegexpInstallerScript +class plgVmShipmentRulesRegexpInstallerScript +{ + /** + * Constructor + * + * @param JAdapterInstance $adapter The object responsible for running this script + */ +// public function __constructor(JAdapterInstance $adapter); + + /** + * Called before any type of action + * + * @param string $route Which action is happening (install|uninstall|discover_install) + * @param JAdapterInstance $adapter The object responsible for running this script + * + * @return boolean True on success + */ +// public function preflight($route, JAdapterInstance $adapter); + + /** + * Called after any type of action + * + * @param string $route Which action is happening (install|uninstall|discover_install) + * @param JAdapterInstance $adapter The object responsible for running this script + * + * @return boolean True on success + */ +// public function postflight($route, JAdapterInstance $adapter); + + /** + * Called on installation + * + * @param JAdapterInstance $adapter The object responsible for running this script + * + * @return boolean True on success + */ + public function install(JAdapterInstance $adapter) + { + // enabling plugin upon installation + $db =& JFactory::getDBO(); + $db->setQuery('update #__extensions set enabled = 1 where type = "plugin" and element = "regexp" and folder = "vmshipmentrules"'); + $db->query(); + + return True; + } + + /** + * Called on update + * + * @param JAdapterInstance $adapter The object responsible for running this script + * + * @return boolean True on success + */ +// public function update(JAdapterInstance $adapter) +// { +// jimport( 'joomla.filesystem.file' ); +// $file = JPATH_ROOT . DS . "administrator" . DS . "language" . DS . "en-GB" . DS . "en-GB.plg_vmshipmentrules_regexp.sys.ini"; +// if (JFile::exists($file)) JFile::delete($file); +// $file = JPATH_ROOT . DS . "administrator" . DS . "language" . DS . "de-DE" . DS . "de-DE.plg_vmshipmentrules_regexp.sys.ini"; +// if (JFile::exists($file)) JFile::delete($file); +// return true; +// } + + /** + * Called on uninstallation + * + * @param JAdapterInstance $adapter The object responsible for running this script + */ +// public function uninstall(JAdapterInstance $adapter) +// { +// // Remove plugin table +// $db =& JFactory::getDBO(); +// $db->setQuery('DROP TABLE IF EXISTS `#__virtuemart_vmshipmentrulesles_regexp`;'); +// $db->query(); +// } +} diff --git a/plugins/regexp/regexp.xml b/plugins/regexp/regexp.xml new file mode 100644 index 0000000..a1f2301 --- /dev/null +++ b/plugins/regexp/regexp.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<extension version="2.5" type="plugin" group="vmshipmentrules" method="upgrade"> + <name>VMSHIPMENTRULES_REGEXP</name> + <creationDate>2014-11-10</creationDate> + <author>Reinhold Kainhofer, Open Tools</author> + <authorUrl>http://www.open-tools.net</authorUrl> + <copyright>Copyright (C) 2014, Reinhold Kainhofer</copyright> + <license>GPL v3+</license> + <version>1.0</version> + <description>VMSHIPMENTRULES_REGEXP_DESC</description> + <files> + <filename plugin="regexp">regexp.php</filename> + <folder>language</folder> + </files> + <languages folder="language"> + <language tag="en-GB">en-GB/en-GB.plg_vmshipmentrules_regexp.ini</language> + <language tag="en-GB">en-GB/en-GB.plg_vmshipmentrules_regexp.sys.ini</language> + </languages> + <scriptfile>regexp.script.php</scriptfile> + + <!-- VM 3.x support (fields rather than params): --> + <vmconfig></vmconfig> + + <!-- VM 2.0 support (params rather than fields): --> + <params></params> + +</extension> diff --git a/plugins/regexp/releases/plg_opentools_vmshipmentrules_regexp_v1.0.zip b/plugins/regexp/releases/plg_opentools_vmshipmentrules_regexp_v1.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..3a17054f812a51a3a0cd4a4ab09080feb159a1fe GIT binary patch literal 4853 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 literal 0 HcmV?d00001 -- GitLab