Skip to content
Snippets Groups Projects
Commit 4b21d4b0 authored by Reinhold Kainhofer's avatar Reinhold Kainhofer
Browse files

Make it work with the generic helper class

parent 381fc86a
Branches
Tags
No related merge requests found
...@@ -18,31 +18,29 @@ defined('DS') or define('DS', DIRECTORY_SEPARATOR); ...@@ -18,31 +18,29 @@ defined('DS') or define('DS', DIRECTORY_SEPARATOR);
if (!class_exists( 'VmConfig' )) if (!class_exists( 'VmConfig' ))
require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php'); require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php');
VmConfig::loadConfig(); VmConfig::loadConfig();
if (!class_exists('OrdernumberHelperJoomla'))
require_once (dirname(dirname(__FILE__)) . DS . 'ordernumber_helper_joomla.php');
class JFormFieldVmOrdernumberCounters extends JFormField { class JFormFieldVmOrdernumberCounters extends JFormField {
var $_name = 'vmOrdernumberCounters'; var $_name = 'vmOrdernumberCounters';
protected $countertype; protected $countertype;
public function __get($name) public function __get($name)
{ {
switch ($name) switch ($name) {
{
case 'countertype': case 'countertype':
return $this->$name; return $this->$name;
} }
return parent::__get($name); return parent::__get($name);
} }
public function __set($name, $value) public function __set($name, $value)
{ {
switch ($name) switch ($name) {
{
case 'countertype': case 'countertype':
$this->$name = (string) $value; $this->$name = (string) $value;
break; break;
default: default:
parent::__set($name, $value); parent::__set($name, $value);
} }
...@@ -59,86 +57,32 @@ class JFormFieldVmOrdernumberCounters extends JFormField { ...@@ -59,86 +57,32 @@ class JFormFieldVmOrdernumberCounters extends JFormField {
return $return; return $return;
} }
// VM2 on J2 works, VM3 on J3 works out of the box, but
// VM3 on J2 does NOT work by simply calling vmJsApi::jQuery, because
// the JS is never added to the page header, so we have to add this manually
protected function loadjQuery() {
vmJsApi::jQuery();
// If we are on Joomla 2.5 and VM 3, manually add the script declarations
// cached in vmJsApi to the document header:
if (version_compare(JVERSION, '3.0', 'lt') && defined('VM_VERSION') && VM_VERSION>=3) {
$document = JFactory::getDocument();
$scripts = vmJsApi::getJScripts();
foreach ($scripts as $name => $jsToAdd) {
if($jsToAdd['written']) continue;
$file = $jsToAdd['script'] ? $jsToAdd['script'] : $name;
if(strpos($file,'/')!==0){ protected function makeJSTranslationsAvailable() {
$file = vmJsApi::setPath($file,false,''); JText::script('PLG_ORDERNUMBER_JS_NOT_AUTHORIZED');
} else if(strpos($file,'//')!==0){ JText::script('PLG_ORDERNUMBER_JS_NEWCOUNTER');
$file = JURI::root(true).$file; JText::script('PLG_ORDERNUMBER_JS_EDITCOUNTER');
} JText::script('PLG_ORDERNUMBER_JS_INVALID_COUNTERVALUE');
JText::script('PLG_ORDERNUMBER_JS_MODIFY_FAILED');
JText::script('PLG_ORDERNUMBER_JS_DELETECOUNTER');
JText::script('PLG_ORDERNUMBER_JS_DELETE_FAILED');
JText::script('PLG_ORDERNUMBER_JS_ADD_FAILED');
JText::script('PLG_ORDERNUMBER_JS_JSONERROR');
}
protected function getInput() {
$helper = OrdernumberHelperJoomla::getHelper();
$ver = ''; $doc = JFactory::getDocument()->addStyleSheet($helper->urlPath('css', 'ordernumber.css'));
if(!empty($jsToAdd['ver'])) $ver = '?vmver='.$jsToAdd['ver']; // $this->makeJSTranslationsAvailable();
$document->addScript( $file .$ver,"text/javascript",$jsToAdd['defer'],$jsToAdd['async'] ); $helper->loadjQuery();
vmJsApi::removeJScript($name); $doc->addScript($helper->urlPath('js', 'ordernumber.js'));
}
}
}
protected function makeJSTranslationsAvailable() {
JText::script('PLG_ORDERNUMBER_JS_NOT_AUTHORIZED');
JText::script('PLG_ORDERNUMBER_JS_NEWCOUNTER');
JText::script('PLG_ORDERNUMBER_JS_EDITCOUNTER');
JText::script('PLG_ORDERNUMBER_JS_INVALID_COUNTERVALUE');
JText::script('PLG_ORDERNUMBER_JS_MODIFY_FAILED');
JText::script('PLG_ORDERNUMBER_JS_DELETECOUNTER');
JText::script('PLG_ORDERNUMBER_JS_DELETE_FAILED');
JText::script('PLG_ORDERNUMBER_JS_ADD_FAILED');
JText::script('PLG_ORDERNUMBER_JS_JSONERROR');
}
protected function getInput() {
$pluginpath = '/plugins/vmshopper/ordernumber/ordernumber/';
$doc = JFactory::getDocument()->addStyleSheet(JURI::root(true) . $pluginpath . 'assets/css/ordernumber.css');
$this->makeJSTranslationsAvailable();
$this->loadjQuery();
$doc->addScript(JURI::root(true).$pluginpath . 'assets/js/ordernumber.js');
// Look up the current counters
$db = JFactory::getDBO();
$db->setQuery('SELECT `number_format`, `count` FROM `#__virtuemart_shopper_plg_ordernumber` WHERE `number_type`='.$db->quote($this->countertype) . ' ORDER BY `number_format`;' );
$counters = $db->loadObjectList();
// Joomla 2.x uses <li> for the params and float:left on the controls, so we need to add that too
$float = "";
if (version_compare(JVERSION, '3.0', 'lt')) {
$float = "float: left; ";
}
$html=array(); // Look up the current counters
$html[] = "<img src='".JURI::root(true).$pluginpath . "assets/images/loading.gif' class='vm-ordernumber-loading' style=\"display: none; position: absolute; top: 2px; left: 0px; z-index: 9999;\"/><table class=\"vmordernumber-countertable table-striped \" style=\"display: inline-table; $float\">"; $db = JFactory::getDBO();
$html[] = " <tr>"; $db->setQuery('SELECT `number_format`, `count` FROM `#__virtuemart_shopper_plg_ordernumber` WHERE `number_type`='.$db->quote($this->countertype) . ' ORDER BY `number_format`;' );
$html[] = " <th class='counter_format'>".JText::_('PLG_ORDERNUMBER_COUNTERLIST_HEADER_COUNTER')."</th>"; $counters = $db->loadObjectList();
$html[] = " <th class='counter_value'>".JText::_('PLG_ORDERNUMBER_COUNTERLIST_HEADER_VALUE'). "</th>";
$html[] = " <th class='counter_buttons'></th>"; return $helper->counter_modification_create_table ($this->countertype, $counters);
$html[] = " </tr>"; }
$html[] = " <colgroup><col class='counter_type'><col style=\"text-align: center\" ><col ></colgroup>"; }
foreach ($counters as $c) {
$displayfmt = $c->number_format;
if ($displayfmt=="") {
$displayfmt = JText::_ ('PLG_ORDERNUMBER_COUNTERLIST_GLOBAL');
}
$html[] = " <tr class='counter_row counter_type_$this->countertype'>";
$html[] = " <td class='counter_format'>" . (string)$displayfmt . "</td>";
$html[] = " <td class='counter_value'>" . (string)$c->count . "</td>";
$html[] = " <td class='counter_buttons'><div class='ordernumber-ajax-loading'><img src='" .JURI::root(true).$pluginpath . "assets/images/icon-16-edit.png' class='vmordernumber-counter-editbtn vmordernumber-btn' onClick='ajaxEditCounter(this, " . json_encode($this->countertype) . ", ".json_encode($c->number_format).", $c->count)' /></div><div class='ordernumber-ajax-loading'><img src='" . JURI::root(true).$pluginpath . "assets/images/icon-16-delete.png' class='vmordernumber-counter-deletebtn vmordernumber-btn' onClick='ajaxDeleteCounter(this, ".json_encode($this->countertype).", ".json_encode($c->number_format).", $c->count)' /></div></td>";
$html[] = " </tr>";
}
$html[] = " <tr class='addcounter_row'>";
$html[] = " <td colspan=3 class='counter_add'><div class='vmordernumber-counter-addbtn vmordernumber-btn' onClick='ajaxAddCounter(this, " . json_encode($this->countertype).")'><div class='ordernumber-ajax-loading'><img src='" . JURI::root(true).$pluginpath . "assets/images/icon-16-new.png' class='vmordernumber-counter-addbtn' /></div>" . JText::_('PLG_ORDERNUMBER_COUNTERLIST_ADD') . "</div></td>";
$html[] = " </tr>";
$html[] = "</table>";
return implode("\n", $html);
}
}
\ No newline at end of file
...@@ -15,180 +15,24 @@ defined('_JEXEC') or die(); ...@@ -15,180 +15,24 @@ defined('_JEXEC') or die();
*/ */
defined('DS') or define('DS', DIRECTORY_SEPARATOR); defined('DS') or define('DS', DIRECTORY_SEPARATOR);
if (!class_exists( 'VmConfig' )) // if (!class_exists( 'VmConfig' ))
require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php'); // require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php');
VmConfig::loadConfig(); // VmConfig::loadConfig();
if (!class_exists('OrdernumberHelperJoomla'))
require_once (dirname(dirname(__FILE__)) . DS . 'ordernumber_helper_joomla.php');
class JFormFieldVmOrdernumberReplacements extends JFormField { class JFormFieldVmOrdernumberReplacements extends JFormField {
var $_name = 'vmOrdernumberReplacements'; var $_name = 'vmOrdernumberReplacements';
static $pluginpath = '/plugins/vmshopper/ordernumber/ordernumber/';
protected function getInput() {
protected $countertype; $helper = OrdernumberHelperJoomla::getHelper();
$doc = JFactory::getDocument()->addStyleSheet($helper->urlPath('css', 'ordernumber.css'));
// VM2 on J2 works, VM3 on J3 works out of the box, but $helper->loadjQuery();
// VM3 on J2 does NOT work by simply calling vmJsApi::jQuery, because $doc->addScriptDeclaration($helper->createJSSetup());
// the JS is never added to the page header, so we have to add this manually $doc->addScript( $helper->urlPath('js', 'ordernumber.js'));
protected function loadjQuery() {
vmJsApi::jQuery();
// TODO: jquery::ui available only in J3:
if (version_compare(JVERSION, '3.0', 'lt')) {
} else {
JHtml::_('jquery.ui', array('core', 'sortable'));
}
// If we are on Joomla 2.5 and VM 3, manually add the script declarations
// cached in vmJsApi to the document header:
if (version_compare(JVERSION, '3.0', 'lt') && defined('VM_VERSION') && VM_VERSION>=3) {
$document = JFactory::getDocument();
$scripts = vmJsApi::getJScripts();
foreach ($scripts as $name => $jsToAdd) {
if($jsToAdd['written']) continue;
$file = $jsToAdd['script'] ? $jsToAdd['script'] : $name;
if(strpos($file,'/')!==0){
$file = vmJsApi::setPath($file,false,'');
} else if(strpos($file,'//')!==0){
$file = JURI::root(true).$file;
}
$ver = '';
if(!empty($jsToAdd['ver'])) $ver = '?vmver='.$jsToAdd['ver'];
$document->addScript( $file .$ver,"text/javascript",$jsToAdd['defer'],$jsToAdd['async'] );
vmJsApi::removeJScript($name);
}
}
}
static function img_url($file) {
return JURI::root(true) . self::$pluginpath . 'assets/images/' . $file;
}
static function css_url($file) {
return JURI::root(true) . self::$pluginpath . 'assets/css/' . $file;
}
static function js_url($file) {
return JURI::root(true) . self::$pluginpath . 'assets/js/' . $file;
}
static function __($string) {
return JText::_($string);
}
protected function makeJSTranslationsAvailable() {
// JText::script('PLG_ORDERNUMBER_JS_JSONERROR');
}
protected function getInput() {
$html=array();
$doc = JFactory::getDocument()->addStyleSheet(self::css_url('ordernumber.css'));
$this->loadjQuery();
$doc->addScript( self::js_url('ordernumber.js'));
$this->makeJSTranslationsAvailable();
$value = $this->value;
// $html[] = "<pre> value: ".print_r($value,1)."</pre>";
// $html[] = "<pre>Form Field: ".print_r($this,1)."</pre>";
$variables = array();
if (!is_array($value))
$value = array();
if (!empty($value)) {
$keys = array_keys($value);
foreach (array_keys($value[$keys[0]]) as $i) {
$entry = array();
foreach ($keys as $k) {
$entry[$k] = $value[$k][$i];
}
$variables[] = $entry;
}
}
$id = $this->id;
$name = $this->name;
$variables = $helper->transposeCustomVariables($this->value);
// $html[] = "<pre>Variables: ".print_r($variables,1)."</pre>"; return $helper->custom_variables_create_table($this->name, $variables);
$html[] = '<table id="ordernumber_variables_template" style="display:none">';
$html[] = $this->create_replacements_row_html($name, array(), 'disabled');
$html[] = '</table>';
$html[] = '<table id="ordernumber_variables" class="ordernumber_variables widefat wc_input_table sortable" cellspacing="0">';
$columns = array(
'variables_ifvar' => self::__('PLG_ORDERNUMBER_REPL_IFVAR'),
'variables_ifop' => '',
'variables_ifval' => self::__('PLG_ORDERNUMBER_REPL_IFVAL'),
'variables_then' => self::__(''),
'variables_thenvar' => self::__('PLG_ORDERNUMBER_REPL_SETVAR'),
'variables_thenval' => self::__('PLG_ORDERNUMBER_REPL_TOVAL'),
'sort' => '',
'variables_settings' => '',
);
$html[] = ' <thead>';
$html[] = ' <tr class="ordernumber_variables_header">';
foreach ( $columns as $key => $column ) {
$html[] = '<th class="' . $key . '">' . htmlspecialchars( $column ) . '</th>';
}
$html[] = ' </tr>';
$html[] = ' <tr id="ordernumber-replacements-empty-row" class="oton-empty-row-notice ' . (empty($variables)?"":"rowhidden") . '">';
$html[] = ' <td class="oton-empty-row-notice" colspan="8">';
$html[] = ' <em>' . self::__('PLG_ORDERNUMBER_REPL_NOCUSTOMVARS') . '</em>';
$html[] = ' <input type="hidden" name="' . $name . '" value="" ' . (empty($variables))?'':'disabled' . '>';
$html[] = ' </td>';
$html[] = ' </tr>';
$html[] = ' </thead>';
$html[] = ' <colgroup>';
foreach ($columns as $key => $column) {
$html[] = '<col class="' . $key . '" />';
}
$html[] = ' </colgroup>';
$html[] = '';
$html[] = ' <tbody>';
foreach ($variables as $var) {
$html[] = $this->create_replacements_row_html($name, $var);
}
$html[] = ' </tbody>';
$html[] = ' <tfoot>';
$html[] = ' <tr class="addreplacement_row">';
$html[] = ' <td colspan=8 class="variable_add">';
$html[] = ' <div class="ordernumber-variables-addbtn ordernumber-btn" onClick="ordernumberVariablesAddRow(\'ordernumber_variables_template\', \'ordernumber_variables\')">';
$html[] = ' <div class="ordernumber-ajax-loading"><img src="' . self::img_url( 'icon-16-new.png' ) . '" class="ordernumber-counter-addbtn" /></div>';
$html[] = self::__('PLG_ORDERNUMBER_REPL_ADDVAR');
$html[] = ' </div>';
$html[] = ' </td>';
$html[] = ' </tr>';
$html[] = ' </tfoot>';
$html[] = '</table>';
return implode("\n", $html);
} }
protected function create_replacements_row_html($name, $values = array(), $disabled = '') {
$operator = (isset($values['conditionop'])?$values['conditionop']:'');
$operators = array(
'equals' => '=',
'contains' => self::__('PLG_ORDERNUMBER_REPL_OP_CONTAINS'),
'smaller' => '<',
'smallerequal' => '<=',
'larger' => '>',
'largerequal' => '>=',
'startswith' => self::__('PLG_ORDERNUMBER_REPL_OP_STARTS'),
'endswith' => self::__('PLG_ORDERNUMBER_REPL_OP_ENDS'),
);
$html = '
<tr>
<td class="variables_ifvar"><input name="' . $name . '[conditionvar][]" value="' . (isset($values['conditionvar'])?$values['conditionvar']:'') . '" ' . $disabled . '/></td>
<td class="variables_ifop" ><select name="' . $name . '[conditionop][]" ' . $disabled . ' style="width: 100px">';
foreach ($operators as $op => $opname) {
$html .= ' <option value="' . $op . '" ' . (($op === $operator)?'selected':'') . '>' . htmlspecialchars($opname) . '</option>';
}
$html .= '</select></td>
<td class="variables_ifval" ><input name="' . $name . '[conditionval][]" value="' . (isset($values['conditionval'])?$values['conditionval']:'') . '" ' . $disabled . '/></td>
<td class="variables_then">=></td>
<td class="variables_thenvar"><input name="' . $name . '[newvar][]" value="' . (isset($values['newvar'])?$values['newvar']:'') . '" ' . $disabled . '/></td>
<td class="variables_thenval"><input name="' . $name . '[newval][]" value="' . (isset($values['newval'])?$values['newval']:'') . '" ' . $disabled . '/></td>
<td class="sort"></td>
<td class="variables_settings"><img src="' . self::img_url( 'icon-16-delete.png' ) . '" class="ordernumber-replacement-deletebtn ordernumber-btn"></td>
</tr>';
return $html;
}
} }
\ No newline at end of file
...@@ -59,15 +59,15 @@ PLG_ORDERNUMBER_FIELDSET_INVOICENUMBER="Invoice Numbers" ...@@ -59,15 +59,15 @@ PLG_ORDERNUMBER_FIELDSET_INVOICENUMBER="Invoice Numbers"
PLG_ORDERNUMBER_FIELDSET_CUSTOMERNUMBER="Customer Numbers" PLG_ORDERNUMBER_FIELDSET_CUSTOMERNUMBER="Customer Numbers"
PLG_ORDERNUMBER_FIELDSET_REPLACEMENTS="Custom Variables" PLG_ORDERNUMBER_FIELDSET_REPLACEMENTS="Custom Variables"
PLG_ORDERNUMBER_JS_NOT_AUTHORIZED="You are not authorized to modify order number counters." ORDERNUMBER_JS_NOT_AUTHORIZED="You are not authorized to modify order number counters."
PLG_ORDERNUMBER_JS_NEWCOUNTER="Please enter the format/name of the new counter:" ORDERNUMBER_JS_NEWCOUNTER="Please enter the format/name of the new counter:"
PLG_ORDERNUMBER_JS_DELETECOUNTER="Really delete counter '{0}' with value '{1}'?" ORDERNUMBER_JS_DELETECOUNTER="Really delete counter '{0}' with value '{1}'?"
PLG_ORDERNUMBER_JS_EDITCOUNTER="{0}Please enter the new value for the counter '{1}' (current value: {2}):" ORDERNUMBER_JS_EDITCOUNTER="{0}Please enter the new value for the counter '{1}' (current value: {2}):"
PLG_ORDERNUMBER_JS_INVALID_COUNTERVALUE="You entered an invalid value for the counter.\n\n" ORDERNUMBER_JS_INVALID_COUNTERVALUE="You entered an invalid value for the counter.\n\n"
PLG_ORDERNUMBER_JS_MODIFY_FAILED="Failed modifying counter {0}" ORDERNUMBER_JS_MODIFY_FAILED="Failed modifying counter {0}"
PLG_ORDERNUMBER_JS_DELETE_FAILED="Failed deleting counter {0}" ORDERNUMBER_JS_DELETE_FAILED="Failed deleting counter {0}"
PLG_ORDERNUMBER_JS_ADD_FAILED="Failed adding counter {0}" ORDERNUMBER_JS_ADD_FAILED="Failed adding counter {0}"
PLG_ORDERNUMBER_JS_JSONERROR="Error reading response from server:" ORDERNUMBER_JS_JSONERROR="Error reading response from server:"
PLG_ORDERNUMBER_REPL_IFVAR="If variable ..." PLG_ORDERNUMBER_REPL_IFVAR="If variable ..."
PLG_ORDERNUMBER_REPL_IFVAL="Value" PLG_ORDERNUMBER_REPL_IFVAL="Value"
......
...@@ -59,15 +59,15 @@ PLG_ORDERNUMBER_FIELDSET_INVOICENUMBER="Invoice Numbers" ...@@ -59,15 +59,15 @@ PLG_ORDERNUMBER_FIELDSET_INVOICENUMBER="Invoice Numbers"
PLG_ORDERNUMBER_FIELDSET_CUSTOMERNUMBER="Customer Numbers" PLG_ORDERNUMBER_FIELDSET_CUSTOMERNUMBER="Customer Numbers"
PLG_ORDERNUMBER_FIELDSET_REPLACEMENTS="Custom Variables" PLG_ORDERNUMBER_FIELDSET_REPLACEMENTS="Custom Variables"
PLG_ORDERNUMBER_JS_NOT_AUTHORIZED="You are not authorized to modify order number counters." ORDERNUMBER_JS_NOT_AUTHORIZED="You are not authorized to modify order number counters."
PLG_ORDERNUMBER_JS_NEWCOUNTER="Please enter the format/name of the new counter:" ORDERNUMBER_JS_NEWCOUNTER="Please enter the format/name of the new counter:"
PLG_ORDERNUMBER_JS_DELETECOUNTER="Really delete counter '{0}' with value '{1}'?" ORDERNUMBER_JS_DELETECOUNTER="Really delete counter '{0}' with value '{1}'?"
PLG_ORDERNUMBER_JS_EDITCOUNTER="{0}Please enter the new value for the counter '{1}' (current value: {2}):" ORDERNUMBER_JS_EDITCOUNTER="{0}Please enter the new value for the counter '{1}' (current value: {2}):"
PLG_ORDERNUMBER_JS_INVALID_COUNTERVALUE="You entered an invalid value for the counter.\n\n" ORDERNUMBER_JS_INVALID_COUNTERVALUE="You entered an invalid value for the counter.\n\n"
PLG_ORDERNUMBER_JS_MODIFY_FAILED="Failed modifying counter {0}" ORDERNUMBER_JS_MODIFY_FAILED="Failed modifying counter {0}"
PLG_ORDERNUMBER_JS_DELETE_FAILED="Failed deleting counter {0}" ORDERNUMBER_JS_DELETE_FAILED="Failed deleting counter {0}"
PLG_ORDERNUMBER_JS_ADD_FAILED="Failed adding counter {0}" ORDERNUMBER_JS_ADD_FAILED="Failed adding counter {0}"
PLG_ORDERNUMBER_JS_JSONERROR="Error reading response from server:" ORDERNUMBER_JS_JSONERROR="Error reading response from server:"
PLG_ORDERNUMBER_REPL_IFVAR="If variable ..." PLG_ORDERNUMBER_REPL_IFVAR="If variable ..."
PLG_ORDERNUMBER_REPL_IFVAL="Value" PLG_ORDERNUMBER_REPL_IFVAL="Value"
......
...@@ -6,21 +6,39 @@ ...@@ -6,21 +6,39 @@
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/ **/
defined('_JEXEC') or die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ) ; if ( !defined( 'ABSPATH' ) and !defined('_JEXEC') ) {
die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ) ;
}
if (!class_exists('vmShopperPlugin')) if (!class_exists('vmShopperPlugin'))
require(JPATH_VM_PLUGINS . DS . 'vmshopperplugin.php'); require(JPATH_VM_PLUGINS . DS . 'vmshopperplugin.php');
if (!class_exists( 'VmConfig' )) // if (!class_exists( 'VmConfig' ))
require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php'); // require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php');
VmConfig::loadConfig(); // VmConfig::loadConfig();
if (!class_exists('OrdernumberHelperJoomla'))
require_once (dirname(__FILE__) . DS . 'ordernumber_helper_joomla.php');
class plgVmShopperOrdernumber extends vmShopperPlugin { class plgVmShopperOrdernumber extends vmShopperPlugin {
protected $helper = null;
function __construct(& $subject, $config) { function __construct(& $subject, $config) {
parent::__construct($subject, $config); parent::__construct($subject, $config);
/* Create the database table */ /* Create the database table */
$this->tableFields = array_keys ($this->getTableSQLFields ()); $this->tableFields = array_keys ($this->getTableSQLFields ());
} $this->helper = new OrdernumberHelperJoomla();
$this->helper->tableName = $this->_tablename;
$this->helper->registerCallback('setupStoreReplacements', array($this, 'setupStoreReplacements'));
$this->helper->registerCallback('setupOrderReplacements', array($this, 'setupOrderReplacements'));
$this->helper->registerCallback('setupUserReplacements', array($this, 'setupUserReplacements'));
$this->helper->registerCallback('setupShippingReplacements', array($this, 'setupShippingReplacements'));
$this->helper->registerCallback('setupThirdPartyReplacements', array($this, 'setupThirdPartyReplacements'));
}
/**
* Glue functions for the OrdernumberHelper
*/
public function getVmPluginCreateTableSQL () { public function getVmPluginCreateTableSQL () {
return $this->createTableSQL ('VM Shopper plugin: custom order and invoice numbers'); return $this->createTableSQL ('VM Shopper plugin: custom order and invoice numbers');
} }
...@@ -38,86 +56,8 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { ...@@ -38,86 +56,8 @@ class plgVmShopperOrdernumber extends vmShopperPlugin {
// We don't need this function, but the parent class declares it abstract, so we need to overload // We don't need this function, but the parent class declares it abstract, so we need to overload
function plgVmOnUpdateOrderBEShopper($_orderID) {} function plgVmOnUpdateOrderBEShopper($_orderID) {}
function _getCounter($nrtype, $format, $default=0) {
$db = JFactory::getDBO();
/* prevent sql injection attacks by escaping the user-entered format! Empty for global counter... */
/* For global counting, simply read the empty number_format entries! */
$q = 'SELECT `count` FROM `'.$this->_tablename.'` WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery($q);
$existing = $db->loadResult();
$count = $existing?$existing:$default;
return $count;
}
function _counterExists($nrtype, $format) {
$db = JFactory::getDBO();
$q = 'SELECT `count` FROM `'.$this->_tablename.'` WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery($q);
return ($db->loadResult() != null);
}
// Insert new counter value into the db
function _addCounter($nrtype, $format, $value) {
$db = JFactory::getDBO();
$q = 'INSERT INTO `'.$this->_tablename.'` (`count`, `number_type`, `number_format`) VALUES ('.(int)$value.','.$db->quote($nrtype).', '.$db->quote($format).')';
$db->setQuery( $q );
$db->query();
return $db->getAffectedRows();
}
// Insert new counter value into the db or update existing one
function _setCounter($nrtype, $format, $value) {
$db = JFactory::getDBO();
$q = 'UPDATE `'.$this->_tablename.'` SET `count`= "'.(int)$value.'" WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery( $q );
$db->query();
if ($db->getAffectedRows()<1) {
return $this->_addCounter($nrtype, $format, $value);
} else {
return $db->getAffectedRows();
}
}
// Insert new counter value into the db or update existing one
function _deleteCounter($nrtype, $format) {
$db = JFactory::getDBO();
$format = $db->escape ($format);
$q = 'DELETE FROM `'.$this->_tablename.'` WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery( $q );
$db->query();
return $db->getAffectedRows();
}
/* Return a random "string" of the given length taken from the given alphabet */
static function randomString($alphabet, $len) {
$alen = strlen($alphabet);
$r = "";
for ($n=0; $n<$len; $n++) {
$r .= $alphabet[mt_rand(0, $alen-1)];
}
return $r;
}
function replaceRandom ($match) {
/* the regexp matches (random)(Type)(Len) as match, Type and Len is optional */
$len = ($match[3]?$match[3]:1);
// Fallback: If no Type is given, use Digit
$alphabet = "0123456789";
// Select the correct alphabet depending on Type
switch (strtolower($match[2])) {
case "digit": $alphabet = "0123456789"; break;
case "hex": $alphabet = "0123456789abcdef"; break;
case "letter": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
case "uletter": $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
case "lletter": $alphabet = "abcdefghijklmnopqrstuvwxyz"; break;
case "alphanum": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; break;
}
return self::randomString ($alphabet, $len);
}
/* Extract the country information from the given ID */ /* Extract the country information from the given ID */
static function getCountryFromID ($country_id) { protected static function getCountryFromID ($country_id) {
$db = JFactory::getDBO(); $db = JFactory::getDBO();
$query = 'SELECT * FROM `#__virtuemart_countries` WHERE `virtuemart_country_id` = ' . (int)$country_id; $query = 'SELECT * FROM `#__virtuemart_countries` WHERE `virtuemart_country_id` = ' . (int)$country_id;
$db->setQuery($query); $db->setQuery($query);
...@@ -126,24 +66,6 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { ...@@ -126,24 +66,6 @@ class plgVmShopperOrdernumber extends vmShopperPlugin {
protected function setupDateTimeReplacements (&$reps, $details, $nrtype) {
$utime = microtime(true);
$reps["[year]"] = date ("Y", $utime);
$reps["[year2]"] = date ("y", $utime);
$reps["[month]"] = date("m", $utime);
$reps["[day]"] = date("d", $utime);
$reps["[hour]"] = date("H", $utime);
$reps["[hour12]"] = date("h", $utime);
$reps["[ampm]"] = date("a", $utime);
$reps["[minute]"] = date("i", $utime);
$reps["[second]"] = date("s", $utime);
$milliseconds = (int)(1000*($utime - (int)$utime));
$millisecondsstring = sprintf('%03d', $milliseconds);
$reps["[decisecond]"] = $millisecondsstring[0];
$reps["[centisecond]"] = substr($millisecondsstring, 0, 2);
$reps["[millisecond]"] = $millisecondsstring;
}
protected function setupStoreReplacements (&$reps, $details, $nrtype) { protected function setupStoreReplacements (&$reps, $details, $nrtype) {
if (isset($details->virtuemart_vendor_id)) if (isset($details->virtuemart_vendor_id))
$reps["[vendorid]"] = $details->virtuemart_vendor_id; $reps["[vendorid]"] = $details->virtuemart_vendor_id;
...@@ -255,7 +177,6 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { ...@@ -255,7 +177,6 @@ class plgVmShopperOrdernumber extends vmShopperPlugin {
} }
protected function setupUserReplacements (&$reps, $details, $nrtype) { protected function setupUserReplacements (&$reps, $details, $nrtype) {
// TODO: Implement shopper group! // TODO: Implement shopper group!
$reps["[userid]"] = $details->virtuemart_user_id; $reps["[userid]"] = $details->virtuemart_user_id;
...@@ -275,160 +196,7 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { ...@@ -275,160 +196,7 @@ class plgVmShopperOrdernumber extends vmShopperPlugin {
JPluginHelper::importPlugin('vmshopper'); JPluginHelper::importPlugin('vmshopper');
JDispatcher::getInstance()->trigger('onVmOrdernumberGetVariables',array(&$reps, $nrtype, $details)); JDispatcher::getInstance()->trigger('onVmOrdernumberGetVariables',array(&$reps, $nrtype, $details));
} }
protected function setupReplacements($nrtype, $details) {
$reps = array();
$this->setupDateTimeReplacements($reps, $details, $nrtype);
$this->setupStoreReplacements($reps, $details, $nrtype);
$this->setupOrderReplacements($reps, $details, $nrtype);
$this->setupUserReplacements($reps, $details, $nrtype);
$this->setupShippingReplacements($reps, $details, $nrtype);
$this->setupThirdPartyReplacements($reps, $details, $nrtype);
return $reps;
}
protected function setupCustomVariables ($nrtype, $order, $reps, $customvars) {
foreach ($customvars as $c) {
$conditionvar = strtolower($c['conditionvar']);
$op = $c['conditionop'];
$found = false;
$match = false;
$compareval = null;
if (isset($reps[$conditionvar])) {
$found = true;
$compareval = $reps[$conditionvar];
} elseif (isset($reps['['.$conditionvar.']'])) {
$found = true;
$compareval = $reps['['.$conditionvar.']'];
}/* elseif ($order && $compareval = $order->getData($conditionvar)) {
// TODO: Handle order property
$found = true;
}*/ else {
// TODO: Handly other possible properties!
// TODO: Print out warning that variable could not be found.
}
if ($found) {
$condval = $c['conditionval'];
switch ($op) {
case 'nocondition':
$match = true; break;
case 'equals':
$match = ($compareval == $condval); break;
case 'contains':
if (is_array($compareval)) {
$match = in_array($condval, $compareval);
} else {
$match = strpos ($compareval, $condval);
}
break;
case 'smaller':
$match = ($compareval<$condval); break;
case 'smallerequal':
$match = ($compareval<=$condval); break;
case 'larger':
$match = ($compareval>$condval); break;
case 'largerequal':
$match = ($compareval>=$condval); break;
case 'startswith':
$match = (substr("$compareval", 0, strlen("$condval")) === "$condval"); break;
case 'endswith':
$match = (substr("$compareval", -strlen("$condval")) === "$condval"); break;
}
} elseif (empty($conditionvar)) {
$match = true;
}
if ($match) {
$varname = '['.strtolower($c['newvar']).']';
$reps[$varname] = $c['newval'];
}
}
return $reps;
}
// Allow the user to override the format like any other custom variable:
protected function setupNumberFormatString($fmt, $type, $order, $reps) {
if (isset($reps['['.$type.'_format]'])) {
return $reps['['.$type.'_format]'];
} else {
return $fmt;
}
}
protected function doReplacements ($fmt, $reps) {
// First, replace all random...[n] fields. This needs to be done with a regexp and a callback:
$fmt = preg_replace_callback ('/\[(random)(.*?)([0-9]*?)\]/', array($this, 'replaceRandom'), $fmt);
// Only use string-valued variables for replacement (array-valued variables can be used in custom variable definitions!)
$reps = array_filter($reps, function($v) { return !is_array($v);} );
return str_ireplace (array_keys($reps), array_values($reps), $fmt);
}
protected function extractCounterSettings ($fmt, $type, $ctrsettings) {
// First, extract all counter settings, i.e. all strings of the form [#####:startval/increment] or [####/increment:startval]
$regexp = '%\[(#+)(/([0-9]+))?(:([0-9]+))?(/([0-9]+))?\]%';
if (preg_match($regexp, $fmt, $counters)) {
// $counters is an array of the form:
// Array (
// [0] => [#####:100/3]
// [1] => #####
// [2] =>
// [3] =>
// [4] => :100
// [5] => 100
// [6] => /3
// [7] => 3
// )
$ctrsettings["${type}_padding"] = strlen($counters[1]);
if (!empty($counters[2])) {
// $counters[2] contains the whole "/n" part, while $counters[3] contains just the step itself
$ctrsettings["${type}_step"] = $counters[3];
}
if (!empty($counters[4])) {
// $counters[4] contains the whole ":n" part, while $counters[5] contains just the start value itself
$ctrsettings["${type}_start"] = $counters[5];
}
if (!empty($counters[6])) {
// $counters[6] contains the whole ":n" part, while $counters[7] contains just the start value itself
$ctrsettings["${type}_step"] = $counters[7];
}
$fmt = preg_replace($regexp, "#", $fmt);
}
// Split at a | to get the number format and a possibly different counter increment format
// If a separate counter format is given after the |, use it, otherwise reuse the number format itself as counter format
$parts = explode ("|", $fmt);
$ctrsettings["${type}_format"] = $parts[0];
$ctrsettings["${type}_counter"] = ($ctrsettings["${type}_global"]==1)?"":$parts[(count($parts)>1)?1:0];
return $ctrsettings;
}
/* replace the variables in the given format. $type indicates the type of number. */
function createNumber ($fmt, $type, $order, $customvars, $ctrsettings) {
$reps = $this->setupReplacements ($type, $order);
$reps = $this->setupCustomVariables ($type, $order, $reps, $customvars);
$format = $this->setupNumberFormatString($fmt, $type, $order, $reps);
$format = $this->doReplacements($format, $reps);
$ctrsettings = $this->extractCounterSettings ($format, $type, $ctrsettings);
// JFactory::getApplication()->enqueueMessage("<pre>Replacements for $type:".print_r($reps,1)."</pre>", 'error');
// Increment the counter only if the format contains a placeholder for it!
if (strpos($ctrsettings["${type}_format"], "#") !== false) {
$countername = $ctrsettings["${type}_counter"];
// Look up the current counter
$count = $this->_getCounter($type, $countername, $ctrsettings["${type}_start"] - $ctrsettings["${type}_step"]) + $ctrsettings["${type}_step"];
$this->_setCounter($type, $countername, $count);
// return the format with the counter inserted
$number = str_replace ("#", sprintf('%0' . $ctrsettings["${type}_padding"] . 's', $count), $ctrsettings["${type}_format"]);
} else {
$number = $ctrsettings["${type}_format"];
}
return $number;
}
function assignNumber($order, $type='ordernumber', $default="#") { function assignNumber($order, $type='ordernumber', $default="#") {
if ($this->params->get('customize_'.$type, 0)) { if ($this->params->get('customize_'.$type, 0)) {
$fmt = $this->params->get ($type.'_format', $default); $fmt = $this->params->get ($type.'_format', $default);
...@@ -440,28 +208,8 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { ...@@ -440,28 +208,8 @@ class plgVmShopperOrdernumber extends vmShopperPlugin {
"${type}_step" => 1, "${type}_step" => 1,
"${type}_start" => 1, "${type}_start" => 1,
); );
$cvar = $this->params->get ('replacements', array()); $customvars = $this->helper->transposeCustomVariables($this->params->get ('replacements', array()));
// Even though the replacements are created and stored as an array, they are retrieved as a stdClass object: $number = $this->helper->createNumber ($fmt, $type, $order, $customvars, $ctrsettings);
if (is_object($cvar)) $cvar = (array)$cvar;
if (!is_array($cvar))
$cvar = array();
// The customvars are stored in transposed form (for technical reasons, since there is no trigger
// called when the corresponding form field from the plugin param is saved)
$customvars = array();
if (!empty($cvar)) {
$keys = array_keys($cvar);
foreach (array_keys($cvar[$keys[0]]) as $i) {
$entry = array();
foreach ($keys as $k) {
$entry[$k] = $cvar[$k][$i];
}
$customvars[] = $entry;
}
}
$number = $this->createNumber ($fmt, $type, $order, $customvars, $ctrsettings);
return $number; return $number;
} else { } else {
return false; return false;
...@@ -542,30 +290,23 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { ...@@ -542,30 +290,23 @@ class plgVmShopperOrdernumber extends vmShopperPlugin {
$json['success'] = 0; // default: unsuccessfull $json['success'] = 0; // default: unsuccessfull
switch ($action) { switch ($action) {
case "deleteCounter": case "deleteCounter":
$json['success'] = $this->_deleteCounter($nrtype, $counter); $json['success'] = $this->helper->deleteCounter($nrtype, $counter);
break; break;
case "addCounter": case "addCounter":
$value = vRequest::getInt('value',0); $value = vRequest::getInt('value',0);
if ($this->_counterExists($nrtype, $counter)) { if ($this->helper->counterExists($nrtype, $counter)) {
$json['error'] = JText::sprintf('PLG_ORDERNUMBER_COUNTERLIST_EXISTS', $counter); $json['error'] = JText::sprintf('PLG_ORDERNUMBER_COUNTERLIST_EXISTS', $counter);
$json['success'] = false; $json['success'] = false;
} else { } else {
$json['success'] = $this->_addCounter($nrtype, $counter, $value); $json['success'] = $this->helper->addCounter($nrtype, $counter, $value);
// Return the table row for the new counter in the JSON: // Return the table row for the new counter in the JSON:
$pluginpath = '/plugins/vmshopper/ordernumber/ordernumber/'; $json['row'] = $this->helper->counter_modification_create_row($nrtype, $counter, $value);
$displayfmt = ($counter=="") ? JText::_('PLG_ORDERNUMBER_COUNTERLIST_GLOBAL') : $counter;
$html=array();
$html[] = "<tr class='counter_row counter_type_$nrtype'>";
$html[] = " <td class='counter_format'>" . (string)$displayfmt . "</td>";
$html[] = " <td class='counter_value'>" . (string)$value . "</td>";
$html[] = " <td class='counter_buttons'><img src='" .JURI::root(true).$pluginpath . "assets/images/icon-16-edit.png' class='vmordernumber-counter-editbtn vmordernumber-btn' onClick='ajaxEditCounter(this, ".json_encode($nrtype).", ".json_encode($counter).", $value)' /><img src='" . JURI::root(true).$pluginpath . "assets/images/icon-16-delete.png' class='vmordernumber-counter-deletebtn vmordernumber-btn' onClick='ajaxDeleteCounter(this, ".json_encode($nrtype).", ".json_encode($counter).", $value)' /></td>";
$html[] = "</tr>";
$json['newrow'] = implode("\n", $html);
} }
break; break;
case "setCounter": case "setCounter":
$value = vRequest::getInt('value'); $value = vRequest::getInt('value');
$json['success'] = $this->_setCounter($nrtype, $counter, $value); $json['success'] = $this->helper->setCounter($nrtype, $counter, $value);
$json['row'] = $this->helper->counter_modification_create_row($nrtype, $counter, $value);
break; break;
} }
......
td.counter_value {
text-align: center;
}
table.vmordernumber-countertable { table.ordernumber-countertable {
border: 1px solid #888888; border: 1px solid #888888;
display: inline-table;
} }
table.vmordernumber-countertable.table-striped tbody > tr:nth-child(odd) > th { table.ordernumber-countertable.table-striped tbody > tr:nth-child(odd) > th {
background: #E0E0E0; background: #E0E0E0;
} }
.vmordernumber-btn { .vmordernumber-btn {
...@@ -16,15 +14,18 @@ table.vmordernumber-countertable.table-striped tbody > tr:nth-child(odd) > th { ...@@ -16,15 +14,18 @@ table.vmordernumber-countertable.table-striped tbody > tr:nth-child(odd) > th {
col.counter_type, th.counter_type, td.counter_type { col.counter_type, th.counter_type, td.counter_type {
display:none; display:none;
} }
td.counter_value {
text-align: center;
}
fieldset table.vmordernumber-countertable img { fieldset table.ordernumber-countertable img {
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
div.ordernumber-ajax-loading, div.vmordernumber-counter-addbtn { div.ordernumber-ajax-loading, div.ordernumber-counter-addbtn {
display: inline; display: inline;
} }
div.ordernumber-ajax-loading, div.ordernumber-ajax-loading img.vmordernumber-btn { div.ordernumber-ajax-loading, div.ordernumber-ajax-loading img.ordernumber-btn {
position: relative; position: relative;
top: 0; left: 0; top: 0; left: 0;
} }
...@@ -32,6 +33,14 @@ div.ordernumber-ajax-loading img { ...@@ -32,6 +33,14 @@ div.ordernumber-ajax-loading img {
z-index:0; z-index:0;
} }
img.ordernumber-loading {
display: none;
position: absolute;
top: 2px;
left: 0px;
z-index: 9999;
}
/* Counter custom variable replacements */ /* Counter custom variable replacements */
...@@ -96,3 +105,6 @@ col.variables_thenvar, col.variables_thenval { ...@@ -96,3 +105,6 @@ col.variables_thenvar, col.variables_thenval {
text-align: center; text-align: center;
width: 20px; width: 20px;
} }
...@@ -3,21 +3,6 @@ ...@@ -3,21 +3,6 @@
* Javascript for the counter modification table * Javascript for the counter modification table
* *
**********************************************************************************/ **********************************************************************************/
var updateMessages = function(messages, area) {
jQuery( "#system-message-container #system-message ."+area+"-message").remove();
// Extract the messages from the returned string, add the ordernumber-message class (so the next ajax call
// can remove them again) and then move the messages to the original message container.
// Things are complicated by the fact that no #system-message element exists if no messages were printed so far
var newmessages = jQuery( messages ).find("div.alert, .message").addClass(area+"-message");
if (!jQuery( "#system-message-container #system-message").length && newmessages.length) {
if (jQuery(newmessages).first().prop("tagName")=="dt") { // Joomla 2.x:
jQuery( "#system-message-container" ).append( "<dl id='system-message'></div>" );
} else {
jQuery( "#system-message-container" ).append( "<div id='system-message'></div>" );
}
}
newmessages.appendTo( "#system-message-container #system-message");
}
String.Format = function() { String.Format = function() {
var s = arguments[0]; var s = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) { for (var i = 0; i < arguments.length - 1; i++) {
...@@ -28,18 +13,19 @@ String.Format = function() { ...@@ -28,18 +13,19 @@ String.Format = function() {
} }
var getCounterData = function (btn) { var getCounterData = function (btn) {
var row=jQuery(btn).parents("tr.counter_row"); return { row: jQuery(btn).closest("tr.counter_row") };
return { row: row };
} }
var handleJSONResponse = function (json, counter) { var handleJSONResponse = function (json, counter) {
updateMessages(json['messages'], "ordernumber"); if ('updateMessages' in ajax_ordernumber) {
if (!json.authorized) { ajax_ordernumber.updateMessages(json['messages'], "ordernumber");
alert(Joomla.JText._('PLG_ORDERNUMBER_JS_NOT_AUTHORIZED', "You are not authorized to modify order number counters.")); }
} else if (json.error) { if (!json.authorized) {
alert(json.error); alert(ajax_ordernumber.ORDERNUMBER_JS_NOT_AUTHORIZED);
} else { } else if (json.error) {
// TODO: Which other error checks can we do? alert(json.error);
} } else {
// TODO: Which other error checks can we do?
}
} }
var ajaxEditCounter = function (btn, nrtype, ctr, value) { var ajaxEditCounter = function (btn, nrtype, ctr, value) {
var counter = getCounterData(btn); var counter = getCounterData(btn);
...@@ -49,36 +35,43 @@ var ajaxEditCounter = function (btn, nrtype, ctr, value) { ...@@ -49,36 +35,43 @@ var ajaxEditCounter = function (btn, nrtype, ctr, value) {
var value = NaN; var value = NaN;
var msgprefix = ""; var msgprefix = "";
while (isNaN(value) && (value != null)) { while (isNaN(value) && (value != null)) {
var editprompt = Joomla.JText._('PLG_ORDERNUMBER_JS_EDITCOUNTER', "{0}Please enter the new value for the counter '{1}' (current value: {2}):"); var editprompt = ajax_ordernumber.ORDERNUMBER_JS_EDITCOUNTER;
value = prompt (String.Format(editprompt, msgprefix, counter.counter, counter.value), counter.value); value = prompt (String.Format(editprompt, msgprefix, counter.counter, counter.value), counter.value);
if (value != null) if (value != null)
value = parseInt(value); value = parseInt(value);
if (isNaN(value)) if (isNaN(value))
msgprefix = Joomla.JText._('PLG_ORDERNUMBER_JS_INVALID_COUNTERVALUE', "You entered an invalid value for the counter.\n\n"); msgprefix = ajax_ordernumber.ORDERNUMBER_JS_INVALID_COUNTERVALUE;
} }
if (value != null) { if (value != null) {
var loading = jQuery("img.vm-ordernumber-loading").first().clone().insertAfter(btn).show(); var loading = jQuery("img.ordernumber-loading").first().clone().insertAfter(btn).show();
jQuery.ajax({ jQuery.ajax({
type: "POST", type: "POST",
cache: false, cache: false,
dataType: "text", // Read text, but interpret as JSON later in the done method (prevents a warning!) dataType: "text", // Read text, but interpret as JSON later in the done method (prevents a warning!)
url: "index.php?option=com_virtuemart&view=plugin&type=vmshopper&name=ordernumber&action=setCounter&format=raw", url: ajax_ordernumber.ajax_url,
data: { nrtype: counter.type, counter: counter.counter, value: value }, data: {
action: 'setCounter',
nrtype: counter.type,
counter: counter.counter,
value: value
},
success: function( data ) { success: function( data ) {
try { try {
var json = jQuery.parseJSON(data); var json = jQuery.parseJSON(data);
handleJSONResponse(json, counter); handleJSONResponse(json, counter);
} catch (e) { } catch (e) {
alert(Joomla.JText._('PLG_ORDERNUMBER_JS_JSONERROR')+"\n"+e); alert(ajax_ordernumber.ORDERNUMBER_JS_JSONERROR+"\n"+e);
return; return;
} }
if (json.success>0) { if (json.success>0) {
jQuery(counter.row).children(".counter_value").text(value); // replace the whole row with the html returned by the AJAX call:
jQuery(counter.row).replaceWith(json.row);
// jQuery(counter.row).find(".counter_value").text(value);
} else { } else {
alert (String.Format(Joomla.JText._('PLG_ORDERNUMBER_JS_MODIFY_FAILED', "Failed modifying counter {0}"), counter.counter)); alert (String.Format(ajax_ordernumber.ORDERNUMBER_JS_MODIFY_FAILED, counter.counter));
} }
}, },
error: function() { alert (String.Format(Joomla.JText._('PLG_ORDERNUMBER_JS_MODIFY_FAILED', "Failed modifying counter {0}"), counter.counter)); }, error: function() { alert (String.Format(ajax_ordernumber.ORDERNUMBER_JS_MODIFY_FAILED, counter.counter)); },
complete: function() { jQuery(loading).remove(); }, complete: function() { jQuery(loading).remove(); },
}); });
} }
...@@ -88,63 +81,71 @@ var ajaxDeleteCounter = function (btn, nrtype, ctr, value) { ...@@ -88,63 +81,71 @@ var ajaxDeleteCounter = function (btn, nrtype, ctr, value) {
counter.type=nrtype; counter.type=nrtype;
counter.counter=ctr; counter.counter=ctr;
counter.value=value; counter.value=value;
var proceed = confirm (String.Format(Joomla.JText._('PLG_ORDERNUMBER_JS_DELETECOUNTER', "Really delete counter '{0}' with value '{1}'?"), counter.counter, counter.value)); var proceed = confirm (String.Format(ajax_ordernumber.ORDERNUMBER_JS_DELETECOUNTER, counter.counter, counter.value));
if (proceed == true) { if (proceed == true) {
var loading = jQuery("img.vm-ordernumber-loading").first().clone().insertAfter(btn).show(); var loading = jQuery("img.ordernumber-loading").first().clone().insertAfter(btn).show();
jQuery.ajax({ jQuery.ajax({
type: "POST", type: "POST",
cache: false, cache: false,
dataType: "text", // Read text, but interpret as JSON later in the done method (prevents a warning!) dataType: "text", // Read text, but interpret as JSON later in the done method (prevents a warning!)
url: "index.php?option=com_virtuemart&view=plugin&type=vmshopper&name=ordernumber&action=deleteCounter&format=raw", url: ajax_ordernumber.ajax_url,
data: { nrtype: counter.type, counter: counter.counter }, data: {
action: 'deleteCounter',
nrtype: counter.type,
counter: counter.counter
},
success: function( data ) { success: function( data ) {
try { try {
var json = jQuery.parseJSON(data); var json = jQuery.parseJSON(data);
handleJSONResponse(json, counter); handleJSONResponse(json, counter);
} catch (e) { } catch (e) {
alert(Joomla.JText._('PLG_ORDERNUMBER_JS_JSONERROR')+"\n"+e); alert(ajax_ordernumber.ORDERNUMBER_JS_JSONERROR+"\n"+e);
return; return;
} }
if (json.success>0) { if (json.success>0) {
jQuery(counter.row).fadeOut(1500, function() { jQuery(counter.row).remove(); }); jQuery(counter.row).fadeOut(1500, function() { jQuery(counter.row).remove(); });
} else { } else {
alert (String.Format(Joomla.JText._('PLG_ORDERNUMBER_JS_DELETE_FAILED', "Failed deleting counter {0}"), counter.counter)); alert (String.Format(ajax_ordernumber.ORDERNUMBER_JS_DELETE_FAILED, counter.counter));
} }
}, },
error: function() { alert (String.Format(Joomla.JText._('PLG_ORDERNUMBER_JS_DELETE_FAILED', "Failed deleting counter {0}"), counter.counter)); }, error: function() { alert (String.Format(ajax_ordernumber.ORDERNUMBER_JS_DELETE_FAILED, counter.counter)); },
complete: function() { jQuery(loading).remove(); }, complete: function() { jQuery(loading).remove(); },
}); });
} }
} }
var ajaxAddCounter = function (btn, nrtype) { var ajaxAddCounter = function (btn, nrtype) {
var row = jQuery(btn).parents("tr.addcounter_row"); var row = jQuery(btn).parents("tr.addcounter_row");
var countername = prompt (Joomla.JText._('PLG_ORDERNUMBER_JS_NEWCOUNTER', "Please enter the format/name of the new counter:")); var countername = prompt (ajax_ordernumber.ORDERNUMBER_JS_NEWCOUNTER);
if (countername != null) { if (countername != null) {
var loading = jQuery("img.vm-ordernumber-loading").first().clone().insertAfter(jQuery(btn).find("img.vmordernumber-counter-addbtn")).show(); var loading = jQuery("img.ordernumber-loading").first().clone().insertAfter(jQuery(btn).find("img.ordernumber-counter-addbtn")).show();
jQuery.ajax({ jQuery.ajax({
type: "POST", type: "POST",
cache: false, cache: false,
dataType: "text", // Read text, but interpret as JSON later in the done method (prevents a warning!) dataType: "text", // Read text, but interpret as JSON later in the done method (prevents a warning!)
url: "index.php?option=com_virtuemart&view=plugin&type=vmshopper&name=ordernumber&action=addCounter&format=raw", url: ajax_ordernumber.ajax_url,
data: { nrtype: nrtype, counter: countername }, data: {
action: "addCounter",
nrtype: nrtype,
counter: countername
},
success: function( data ) { success: function( data ) {
var json = data ? jQuery.parseJSON(data) : null; var json = data ? jQuery.parseJSON(data) : null;
try { try {
var json = jQuery.parseJSON(data); var json = jQuery.parseJSON(data);
handleJSONResponse(json, null); handleJSONResponse(json, null);
} catch (e) { } catch (e) {
alert(Joomla.JText._('PLG_ORDERNUMBER_JS_JSONERROR')+"\n"+e); alert(ajax_ordernumber.ORDERNUMBER_JS_JSONERROR+"\n"+e);
return; return;
} }
if (json.success>0) { if (json.success>0) {
if (json.newrow) { if (json.row) {
jQuery(row).before(jQuery(json.newrow)); jQuery(row).before(jQuery(json.row));
} }
} else { } else {
alert (String.Format(Joomla.JText._('PLG_ORDERNUMBER_JS_ADD_FAILED', "Failed adding counter {0}"), countername)); alert (String.Format(ajax_ordernumber.ORDERNUMBER_JS_ADD_FAILED, countername));
} }
}, },
error: function() { alert (String.Format(Joomla.JText._('PLG_ORDERNUMBER_JS_ADD_FAILED', "Failed adding counter {0}"), countername)); }, error: function() { alert (String.Format(ajax_ordernumber.ORDERNUMBER_JS_ADD_FAILED, countername)); },
complete: function() { jQuery(loading).remove(); }, complete: function() { jQuery(loading).remove(); },
}); });
} }
......
<?php
/**
* Advanced Ordernumbers generic helper class (e-commerce system agnostic)
* Reinhold Kainhofer, Open Tools, office@open-tools.net
* @copyright (C) 2012-2015 - Reinhold Kainhofer
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/
defined('_JEXEC') or die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ) ;
class OrdernumberHelper {
protected $_callbacks = array();
public $_styles = array(
'counter-table-class' => "table-striped",
'counter-table-style' => "",
'variable-table-class' => "",
'variable-table-style' => "",
);
/**
* An array containing all language keys for the translations used in the JavaScript code.
* Make sure to set those in the ajax_ordernumber JavaScript array!
*/
public $jstranslations = array(
"ORDERNUMBER_JS_NOT_AUTHORIZED", "ORDERNUMBER_JS_INVALID_COUNTERVALUE", "ORDERNUMBER_JS_JSONERROR",
"ORDERNUMBER_JS_NEWCOUNTER", "ORDERNUMBER_JS_EDITCOUNTER", "ORDERNUMBER_JS_DELETECOUNTER",
"ORDERNUMBER_JS_ADD_FAILED", "ORDERNUMBER_JS_MODIFY_FAILED", "ORDERNUMBER_JS_DELETE_FAILED",
);
/**
* The URL to call for AJAX calls
*/
public $ajax_url = "";
function __construct() {
// Set up
$this->registerCallback ("setupDateTimeReplacements", array($this, "setupDateTimeReplacements"));
}
function getStyle($key) {
if (isset($this->_styles[$key])) {
return $this->_styles[$key];
} else {
return '';
}
}
/* Callback handling */
/**
* Register a callback for one of the known callback hooks.
* Valid callbacks are (together with their arguments):
* - translate($string)
* - getCounter($type, $countername, $default)
* - setCounter($type, $countername, $value)
* - setupDateTimeReplacements(&$reps, $details, $nrtype);
* - setupStoreReplacements(&$reps, $details, $nrtype);
* - setupOrderReplacements(&$reps, $details, $nrtype);
* - setupUserReplacements(&$reps, $details, $nrtype);
* - setupShippingReplacements(&$reps, $details, $nrtype);
* - setupThirdPartyReplacements(&$reps, $details, $nrtype);
* - urlPath($path, $type)
* @param string $callback
* The name of the callback hook (string)
* @param function $func
* The function (usually a member of the plugin object) for the callback
* @return none
*/
public function registerCallback($callback, $func) {
$this->callbacks[$callback] = $func;
}
public function __($string) {
if (isset($this->callbacks["translate"])) {
return $this->callbacks["translate"]($string);
} else {
return $string;
}
}
public function urlPath($type, $file) {
if (isset($this->callbacks['urlPath'])) {
return $this->callbacks['urlPath']($type, $file);
} else {
throw new Exception('No callback defined for urlPath(type, file)!');
}
}
protected function replacementsCallback ($func, &$reps, $details, $nrtype) {
if (isset($this->callbacks[$func])) {
return $this->callbacks[$func]($reps, $details, $nrtype);
}
}
protected function getCounter($type, $countername, $default) {
if (isset($this->callbacks['getCounter'])) {
return $this->callbacks['getCounter']($type, $countername, $default);
} else {
throw new Exception('No callback defined for getCounter(type, countername, default)!');
}
}
protected function setCounter($type, $countername, $value) {
if (isset($this->callbacks['getCounter'])) {
return $this->callbacks['getCounter']($type, $countername, $value);
} else {
throw new Exception('No callback defined for setCounter(type, countername, value)!');
}
}
/* Return a random "string" of the given length taken from the given alphabet */
protected static function randomString($alphabet, $len) {
$alen = strlen($alphabet);
$r = "";
for ($n=0; $n<$len; $n++) {
$r .= $alphabet[mt_rand(0, $alen-1)];
}
return $r;
}
protected function replaceRandom ($match) {
/* the regexp matches (random)(Type)(Len) as match, Type and Len is optional */
$len = ($match[3]?$match[3]:1);
// Fallback: If no Type is given, use Digit
$alphabet = "0123456789";
// Select the correct alphabet depending on Type
switch (strtolower($match[2])) {
case "digit": $alphabet = "0123456789"; break;
case "hex": $alphabet = "0123456789abcdef"; break;
case "letter": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
case "uletter": $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
case "lletter": $alphabet = "abcdefghijklmnopqrstuvwxyz"; break;
case "alphanum": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; break;
}
return self::randomString ($alphabet, $len);
}
protected function setupDateTimeReplacements (&$reps, $details, $nrtype) {
$utime = microtime(true);
$reps["[year]"] = date ("Y", $utime);
$reps["[year2]"] = date ("y", $utime);
$reps["[month]"] = date("m", $utime);
$reps["[day]"] = date("d", $utime);
$reps["[hour]"] = date("H", $utime);
$reps["[hour12]"] = date("h", $utime);
$reps["[ampm]"] = date("a", $utime);
$reps["[minute]"] = date("i", $utime);
$reps["[second]"] = date("s", $utime);
$milliseconds = (int)(1000*($utime - (int)$utime));
$millisecondsstring = sprintf('%03d', $milliseconds);
$reps["[decisecond]"] = $millisecondsstring[0];
$reps["[centisecond]"] = substr($millisecondsstring, 0, 2);
$reps["[millisecond]"] = $millisecondsstring;
}
protected function setupReplacements($nrtype, $details) {
$reps = array();
// The following callbacks directly modify the replacements!
$this->replacementsCallback("setupDateTimeReplacements", $reps, $details, $nrtype);
$this->replacementsCallback("setupStoreReplacements", $reps, $details, $nrtype);
$this->replacementsCallback("setupOrderReplacements", $reps, $details, $nrtype);
$this->replacementsCallback("setupUserReplacements", $reps, $details, $nrtype);
$this->replacementsCallback("setupShippingReplacements", $reps, $details, $nrtype);
$this->replacementsCallback("setupThirdPartyReplacements", $reps, $details, $nrtype);
return $reps;
}
protected function setupCustomVariables ($nrtype, $order, $reps, $customvars) {
foreach ($customvars as $c) {
$conditionvar = strtolower($c['conditionvar']);
$op = $c['conditionop'];
$found = false;
$match = false;
$compareval = null;
if (isset($reps[$conditionvar])) {
$found = true;
$compareval = $reps[$conditionvar];
} elseif (isset($reps['['.$conditionvar.']'])) {
$found = true;
$compareval = $reps['['.$conditionvar.']'];
}/* elseif ($order && $compareval = $order->getData($conditionvar)) {
// TODO: Handle order property
$found = true;
}*/ else {
// TODO: Handly other possible properties!
// TODO: Print out warning that variable could not be found.
}
if ($found) {
$condval = $c['conditionval'];
switch ($op) {
case 'nocondition':
$match = true; break;
case 'equals':
$match = ($compareval == $condval); break;
case 'contains':
if (is_array($compareval)) {
$match = in_array($condval, $compareval);
} else {
$match = strpos ($compareval, $condval);
}
break;
case 'smaller':
$match = ($compareval<$condval); break;
case 'smallerequal':
$match = ($compareval<=$condval); break;
case 'larger':
$match = ($compareval>$condval); break;
case 'largerequal':
$match = ($compareval>=$condval); break;
case 'startswith':
$match = (substr("$compareval", 0, strlen("$condval")) === "$condval"); break;
case 'endswith':
$match = (substr("$compareval", -strlen("$condval")) === "$condval"); break;
}
} elseif (empty($conditionvar)) {
$match = true;
}
if ($match) {
$varname = '['.strtolower($c['newvar']).']';
$reps[$varname] = $c['newval'];
}
}
return $reps;
}
// Allow the user to override the format like any other custom variable:
protected function setupNumberFormatString($fmt, $type, $order, $reps) {
if (isset($reps['['.$type.'_format]'])) {
return $reps['['.$type.'_format]'];
} else {
return $fmt;
}
}
protected function doReplacements ($fmt, $reps) {
// First, replace all random...[n] fields. This needs to be done with a regexp and a callback:
$fmt = preg_replace_callback ('/\[(random)(.*?)([0-9]*?)\]/', array($this, 'replaceRandom'), $fmt);
// Only use string-valued variables for replacement (array-valued variables can be used in custom variable definitions!)
$reps = array_filter($reps, function($v) { return !is_array($v);} );
return str_ireplace (array_keys($reps), array_values($reps), $fmt);
}
protected function extractCounterSettings ($fmt, $type, $ctrsettings) {
// First, extract all counter settings, i.e. all strings of the form [#####:startval/increment] or [####/increment:startval]
$regexp = '%\[(#+)(/([0-9]+))?(:([0-9]+))?(/([0-9]+))?\]%';
if (preg_match($regexp, $fmt, $counters)) {
// $counters is an array of the form:
// Array (
// [0] => [#####:100/3]
// [1] => #####
// [2] =>
// [3] =>
// [4] => :100
// [5] => 100
// [6] => /3
// [7] => 3
// )
$ctrsettings["${type}_padding"] = strlen($counters[1]);
if (!empty($counters[2])) {
// $counters[2] contains the whole "/n" part, while $counters[3] contains just the step itself
$ctrsettings["${type}_step"] = $counters[3];
}
if (!empty($counters[4])) {
// $counters[4] contains the whole ":n" part, while $counters[5] contains just the start value itself
$ctrsettings["${type}_start"] = $counters[5];
}
if (!empty($counters[6])) {
// $counters[6] contains the whole ":n" part, while $counters[7] contains just the start value itself
$ctrsettings["${type}_step"] = $counters[7];
}
$fmt = preg_replace($regexp, "#", $fmt);
}
// Split at a | to get the number format and a possibly different counter increment format
// If a separate counter format is given after the |, use it, otherwise reuse the number format itself as counter format
$parts = explode ("|", $fmt);
$ctrsettings["${type}_format"] = $parts[0];
$ctrsettings["${type}_counter"] = ($ctrsettings["${type}_global"]=='yes')?"":$parts[(count($parts)>1)?1:0];
return $ctrsettings;
}
/**
* Create a number of given type for the given format. Optionally, custom variable definitions and counter formatting can be passed.
* @param fmt The Format of the number (containing variables as [variable] and the counter as # or [####:initial/step])
* @param type The type of the number format, typically order_number, invoice_number, etc. (depending on the e-commerce suite)
* @param order The e-commerce-suite specific object describing the order. This will simply be passed on to the replacement hooks function for further data extraction during variable setup
* @param customvars Definitions (conditions and values) for custom variables. An array of arrays with keys conditionvar, conditionop, conditionval, newvar, newval
* @param ctrsettings Counter formatting defaults (will be overridden by an explicit counter formating variable of [####:initial/step] in the format). Array keys are: $type_format, $type_counter, $type_global, $type_padding, $type_step, $type_start
* @return A new number for the given format. The incremented counter has been properly stored.
*/
public function createNumber ($fmt, $type, $order, $customvars, $ctrsettings) {
$reps = $this->setupReplacements ($type, $order);
$reps = $this->setupCustomVariables ($type, $order, $reps, $customvars);
$format = $this->setupNumberFormatString($fmt, $type, $order, $reps);
$format = $this->doReplacements($format, $reps);
$ctrsettings = $this->extractCounterSettings ($format, $type, $ctrsettings);
// JFactory::getApplication()->enqueueMessage("<pre>Replacements for $type:".print_r($reps,1)."</pre>", 'error');
// Increment the counter only if the format contains a placeholder for it!
if (strpos($ctrsettings["${type}_format"], "#") !== false) {
$countername = $ctrsettings["${type}_counter"];
// Look up the current counter
$count = $this->getCounter($type, $countername, $ctrsettings["${type}_start"] - $ctrsettings["${type}_step"]) + $ctrsettings["${type}_step"];
$this->setCounter($type, $countername, $count);
// return the format with the counter inserted
$number = str_replace ("#", sprintf('%0' . $ctrsettings["${type}_padding"] . 's', $count), $ctrsettings["${type}_format"]);
} else {
$number = $ctrsettings["${type}_format"];
}
return $number;
}
/**
* Create the counter modification HTML table
* @param $type string
*
* @param
*/
public function counter_modification_create_table($type, $counters) {
/* $pluginpath = '/plugins/shopper/ordernumber/ordernumber/';
$doc = JFactory::getDocument()->addStyleSheet(JURI::root(true) . $pluginpath . 'assets/css/ordernumber.css');
$this->makeJSTranslationsAvailable();
$this->loadjQuery();
$doc->addScript(JURI::root(true).$pluginpath . 'assets/js/ordernumber.js');
// Look up the current counters
$db = JFactory::getDBO();
$db->setQuery('SELECT `number_format`, `count` FROM `#__virtuemart_shopper_plg_ordernumber` WHERE `number_type`='.$db->quote($type) . ' ORDER BY `number_format`;' );
$counters = $db->loadObjectList();
// Joomla 2.x uses <li> for the params and float:left on the controls, so we need to add that too
$float = "";
if (version_compare(JVERSION, '3.0', 'lt')) {
$float = "float: left; ";
}
*/
$html=array();
$html[] = "<img src='" . $this->urlPath ('images', 'loading.gif') . "' class='ordernumber-loading' style=\"display: none; position: absolute; top: 2px; left: 0px; z-index: 9999;\"/>";
$html[] = "<table class=\"ordernumber-countertable " . $this->getStyle('counter-table-class') . "\" " . $this->getStyle('counter-table-style') . ">";
$html[] = " <tr>";
$html[] = " <th class='counter_format'>" . $this->__ ('PLG_ORDERNUMBER_COUNTERLIST_HEADER_COUNTER')."</th>";
$html[] = " <th class='counter_value'>" . $this->__ ('PLG_ORDERNUMBER_COUNTERLIST_HEADER_VALUE'). "</th>";
$html[] = " <th class='counter_buttons'></th>";
$html[] = " </tr>";
$html[] = " <colgroup><col class='counter_type'><col style=\"text-align: center\" ><col ></colgroup>";
foreach ($counters as $c) {
$html[] = $this->counter_modification_create_row ($type, $c->number_format, $c->count);
}
$html[] = " <tr class='addcounter_row'>";
$html[] = " <td colspan=3 class='counter_add'>";
$html[] = " <div class='ordernumber-counter-addbtn ordernumber-btn' onClick='ajaxAddCounter(this, " . json_encode($type).")'>";
$html[] = " <div class='ordernumber-ajax-loading'>";
$html[] = " <img src='" . $this->urlPath('images', 'icon-16-new.png') . "' class='ordernumber-counter-addbtn' />";
$html[] = " </div>" . $this->__('PLG_ORDERNUMBER_COUNTERLIST_ADD');
$html[] = " </div>";
$html[] = " </td>";
$html[] = " </tr>";
$html[] = "</table>";
return implode("\n", $html);
}
public function counter_modification_create_row ($type, $counter, $value) {
$html=array();
$html[] = " <tr class='counter_row counter_row_$type'>";
$html[] = " <td class='counter_format'>" . (string)(($counter=="")?($this->__ ('PLG_ORDERNUMBER_COUNTERLIST_GLOBAL')):$counter) . "</td>";
$html[] = " <td class='counter_value'>" . (string)$value . "</td>";
$html[] = " <td class='counter_buttons'>";
$html[] = " <div class='ordernumber-ajax-loading'>";
$html[] = " <img src='" . $this->urlPath('images', 'icon-16-edit.png') . "' class='ordernumber-counter-editbtn ordernumber-btn' ";
$html[] = " onClick='ajaxEditCounter(this, " . json_encode($type) . ", ".json_encode($counter).", $value)' />";
$html[] = " </div>";
$html[] = " <div class='ordernumber-ajax-loading'>";
$html[] = " <img src='" . $this->urlPath ('images', 'icon-16-delete.png') . "' class='ordernumber-counter-deletebtn ordernumber-btn' ";
$html[] = " onClick='ajaxDeleteCounter(this, ".json_encode($type).", ".json_encode($counter).", $value)' />";
$html[] = " </div>";
$html[] = " </td>";
$html[] = " </tr>";
return implode("\n", $html);
}
/**
* Create the html table (with AJAX) to define and modify custom variable definitions.
* The returned HTML code assumes that the caller properly adds the ordernumber.css
* and ordernumber.js to the page and loads the jQuery library.
* @param name string
* The HTML post/request variable name for the control.
* @param variables array
* The current list of custom variable replacements
*
* @retval string
* The HTML code for the custom variable definition table.
*/
public function custom_variables_create_table($name, $variables) {
$html=array();
// $html[] = "<pre>Variables: ".print_r($variables,1)."</pre>";
$html[] = '<table id="ordernumber_variables_template" style="display:none">';
$html[] = $this->custom_variables_create_row($name, array(), 'disabled');
$html[] = '</table>';
$html[] = '<table id="ordernumber_variables" class="ordernumber_variables ' . $this->getStyle('variable-table-class') . '" cellspacing="0" ' . $this->getStyle('variable-table-style') . '>';
$columns = array(
'variables_ifvar' => $this->__('PLG_ORDERNUMBER_REPL_IFVAR'),
'variables_ifop' => '',
'variables_ifval' => $this->__('PLG_ORDERNUMBER_REPL_IFVAL'),
'variables_then' => $this->__(''),
'variables_thenvar' => $this->__('PLG_ORDERNUMBER_REPL_SETVAR'),
'variables_thenval' => $this->__('PLG_ORDERNUMBER_REPL_TOVAL'),
'sort' => '',
'variables_settings' => '',
);
$html[] = ' <thead>';
$html[] = ' <tr class="ordernumber_variables_header">';
foreach ( $columns as $key => $column ) {
$html[] = '<th class="' . $key . '">' . htmlspecialchars( $column ) . '</th>';
}
$html[] = ' </tr>';
$html[] = ' <tr id="ordernumber-replacements-empty-row" class="oton-empty-row-notice ' . (empty($variables)?"":"rowhidden") . '">';
$html[] = ' <td class="oton-empty-row-notice" colspan="8">';
$html[] = ' <em>' . $this->__('PLG_ORDERNUMBER_REPL_NOCUSTOMVARS') . '</em>';
$html[] = ' <input type="hidden" name="' . $name . '" value="" ' . (empty($variables))?'':'disabled' . '>';
$html[] = ' </td>';
$html[] = ' </tr>';
$html[] = ' </thead>';
$html[] = ' <colgroup>';
foreach ($columns as $key => $column) {
$html[] = '<col class="' . $key . '" />';
}
$html[] = ' </colgroup>';
$html[] = '';
$html[] = ' <tbody>';
foreach ($variables as $var) {
$html[] = $this->custom_variables_create_row($name, $var);
}
$html[] = ' </tbody>';
$html[] = ' <tfoot>';
$html[] = ' <tr class="addreplacement_row">';
$html[] = ' <td colspan=8 class="variable_add">';
$html[] = ' <div class="ordernumber-variables-addbtn ordernumber-btn" onClick="ordernumberVariablesAddRow(\'ordernumber_variables_template\', \'ordernumber_variables\')">';
$html[] = ' <div class="ordernumber-ajax-loading"><img src="' . $this->urlPath('images', 'icon-16-new.png' ) . '" class="ordernumber-counter-addbtn" /></div>';
$html[] = $this->__('PLG_ORDERNUMBER_REPL_ADDVAR');
$html[] = ' </div>';
$html[] = ' </td>';
$html[] = ' </tr>';
$html[] = ' </tfoot>';
$html[] = '</table>';
return implode("\n", $html);
}
public function custom_variables_create_row($name, $values = array(), $disabled = '') {
$operator = (isset($values['conditionop'])?$values['conditionop']:'');
$operators = array(
'nocondition' => $this->__('PLG_ORDERNUMBER_REPL_OP_NOCOND'),
'equals' => '=',
'contains' => $this->__('PLG_ORDERNUMBER_REPL_OP_CONTAINS'),
'smaller' => '<',
'smallerequal' => '<=',
'larger' => '>',
'largerequal' => '>=',
'startswith' => $this->__('PLG_ORDERNUMBER_REPL_OP_STARTS'),
'endswith' => $this->__('PLG_ORDERNUMBER_REPL_OP_ENDS'),
);
$html = '
<tr>
<td class="variables_ifvar"><input name="' . $name . '[conditionvar][]" value="' . (isset($values['conditionvar'])?$values['conditionvar']:'') . '" ' . $disabled . '/></td>
<td class="variables_ifop" ><select name="' . $name . '[conditionop][]" ' . $disabled . ' style="width: 100px">';
foreach ($operators as $op => $opname) {
$html .= ' <option value="' . $op . '" ' . (($op === $operator)?'selected':'') . '>' . htmlspecialchars($opname) . '</option>';
}
$html .= '</select></td>
<td class="variables_ifval" ><input name="' . $name . '[conditionval][]" value="' . (isset($values['conditionval'])?$values['conditionval']:'') . '" ' . $disabled . '/></td>
<td class="variables_then">=></td>
<td class="variables_thenvar"><input name="' . $name . '[newvar][]" value="' . (isset($values['newvar'])?$values['newvar']:'') . '" ' . $disabled . '/></td>
<td class="variables_thenval"><input name="' . $name . '[newval][]" value="' . (isset($values['newval'])?$values['newval']:'') . '" ' . $disabled . '/></td>
<td class="sort"></td>
<td class="variables_settings"><img src="' . $this->urlPath('images', 'icon-16-delete.png' ) . '" class="ordernumber-replacement-deletebtn ordernumber-btn"></td>
</tr>';
return $html;
}
/**
* Modify the json that contains JavaScript setup code to be used by ordernumber.js
*/
function addCustomJS(&$json) {}
function appendJS() {}
function createJSSetup() {
static $done = 0; // <= prevent double js code
$json = array();
$json['ajax_url'] = $this->ajax_url;
foreach ($this->jstranslations as $key) {
$json[$key] = $this->__($key);
}
$this->addCustomJS($json);
$js='/* <![CDATA[ */
var ajax_ordernumber = ' . json_encode($json) . ';
';
$js .= $this->appendJS();
$js .= '/* ]]> */
';
$done = 1;
return $js;
}
}
<?php
/**
* Advanced Ordernumbers generic helper class (e-commerce system agnostic)
* Reinhold Kainhofer, Open Tools, office@open-tools.net
* @copyright (C) 2012-2015 - Reinhold Kainhofer
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/
defined('_JEXEC') or die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ) ;
if (!class_exists( 'VmConfig' ))
require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php');
VmConfig::loadConfig();
if (!class_exists( 'OrdernumberHelper' ))
require_once (dirname(__FILE__) . DS . 'ordernumber_helper.php');
class OrdernumberHelperJoomla extends OrdernumberHelper {
public $tableName = '';
function __construct() {
parent::__construct();
// Joomla-specific Defaults for the HTML tables
$this->_styles['counter-table-class'] = "table-striped";
$this->ajax_url = "index.php?option=com_virtuemart&view=plugin&type=vmshopper&name=ordernumber&format=raw";
// Joomla 2.x uses <li> for the params and float:left on the controls, so we need to add that too
if (version_compare(JVERSION, '3.0', 'lt')) {
$this->_styles['counter-table-style'] = "style=\"float: left;\"";
}
}
static function getHelper() {
static $helper = null;
if (!$helper) {
$helper = new OrdernumberHelperJoomla();
}
return $helper;
}
// VM2 on J2 works, VM3 on J3 works out of the box, but
// VM3 on J2 does NOT work by simply calling vmJsApi::jQuery, because
// the JS is never added to the page header, so we have to add this manually
public function loadjQuery() {
vmJsApi::jQuery();
// TODO: jquery::ui available only in J3:
if (version_compare(JVERSION, '3.0', 'lt')) {
} else {
JHtml::_('jquery.ui', array('core', 'sortable'));
}
// If we are on Joomla 2.5 and VM 3, manually add the script declarations
// cached in vmJsApi to the document header:
if (version_compare(JVERSION, '3.0', 'lt') && defined('VM_VERSION') && VM_VERSION>=3) {
$document = JFactory::getDocument();
$scripts = vmJsApi::getJScripts();
foreach ($scripts as $name => $jsToAdd) {
if($jsToAdd['written']) continue;
$file = $jsToAdd['script'] ? $jsToAdd['script'] : $name;
if(strpos($file,'/')!==0){
$file = vmJsApi::setPath($file,false,'');
} else if(strpos($file,'//')!==0){
$file = JURI::root(true).$file;
}
$ver = '';
if(!empty($jsToAdd['ver'])) $ver = '?vmver='.$jsToAdd['ver'];
$document->addScript( $file .$ver,"text/javascript",$jsToAdd['defer'],$jsToAdd['async'] );
vmJsApi::removeJScript($name);
}
}
}
public static function transposeCustomVariables($cvar) {
if (is_object($cvar))
$cvar = (array)$cvar;
if (!is_array($cvar))
$cvar = array();
// The customvars are stored in transposed form (for technical reasons, since there is no trigger
// called when the corresponding form field from the plugin param is saved)
$customvars = array();
if (!empty($cvar)) {
$keys = array_keys($cvar);
foreach (array_keys($cvar[$keys[0]]) as $i) {
$entry = array();
foreach ($keys as $k) {
$entry[$k] = $cvar[$k][$i];
}
$customvars[] = $entry;
}
}
return $customvars;
}
public function __($string) {
// print("<pre>translating: $string</pre>");
return JText::_($string);
}
function urlPath($type, $file) {
static $pluginpath = '/plugins/vmshopper/ordernumber/ordernumber/';
return JURI::root(true) . $pluginpath . 'assets/' . $type . '/' . $file;
}
function getCounter($nrtype, $format, $default=0) {
$db = JFactory::getDBO();
/* prevent sql injection attacks by escaping the user-entered format! Empty for global counter... */
/* For global counting, simply read the empty number_format entries! */
$q = 'SELECT `count` FROM `'.$this->tableName.'` WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery($q);
$existing = $db->loadResult();
$count = $existing?$existing:$default;
return $count;
}
function counterExists($nrtype, $format) {
$db = JFactory::getDBO();
$q = 'SELECT `count` FROM `'.$this->tableName.'` WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery($q);
return ($db->loadResult() != null);
}
// Insert new counter value into the db
function addCounter($nrtype, $format, $value) {
$db = JFactory::getDBO();
$q = 'INSERT INTO `'.$this->tableName.'` (`count`, `number_type`, `number_format`) VALUES ('.(int)$value.','.$db->quote($nrtype).', '.$db->quote($format).')';
$db->setQuery( $q );
$db->query();
return $db->getAffectedRows();
}
// Insert new counter value into the db or update existing one
function setCounter($nrtype, $format, $value) {
$db = JFactory::getDBO();
$q = 'UPDATE `'.$this->tableName.'` SET `count`= "'.(int)$value.'" WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery( $q );
$db->query();
if ($db->getAffectedRows()<1) {
return $this->addCounter($nrtype, $format, $value);
} else {
return $db->getAffectedRows();
}
}
// Insert new counter value into the db or update existing one
function deleteCounter($nrtype, $format) {
$db = JFactory::getDBO();
$format = $db->escape ($format);
$q = 'DELETE FROM `'.$this->tableName.'` WHERE `number_type`='.$db->quote($nrtype).' AND `number_format`='.$db->quote($format);
$db->setQuery( $q );
$db->query();
return $db->getAffectedRows();
}
function appendJS() {
// Extract the messages from the returned string, add the ordernumber-message class (so the next ajax call
// can remove them again) and then move the messages to the original message container.
// Things are complicated by the fact that no #system-message element exists if no messages were printed so far
return 'ajax_ordernumber.updateMessages = function(messages, area) {
jQuery( "#system-message-container #system-message ."+area+"-message").remove();
var newmessages = jQuery( messages ).find("div.alert, .message").addClass(area+"-message");
if (!jQuery( "#system-message-container #system-message").length && newmessages.length) {
if (jQuery(newmessages).first().prop("tagName")=="dt") { // Joomla 2.x:
jQuery( "#system-message-container" ).append( "<dl id=\'system-message\'></div>" );
} else {
jQuery( "#system-message-container" ).append( "<div id=\'system-message\'></div>" );
}
}
newmessages.appendTo( "#system-message-container #system-message");
}';
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment