Plugin Directory

Changeset 3397996


Ignore:
Timestamp:
11/18/2025 11:21:10 AM (4 months ago)
Author:
lwsdevelopers
Message:

Update - Embedded styling tool supports media query. Feature - Add paging to User points history shortcode. Dev - Add filter to force arbitrary price on free product. Fix - Auto-apply coupon case sensitivity. Fix - Edit WC React cart failed with points on cart. Fix - Points-on-cart Coupon duplication in Order edition page after a status update.

Location:
woorewards/trunk
Files:
3 added
2 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • woorewards/trunk/assets/lws-adminpanel/include/tools/pseudocss.php

    r3188612 r3397996  
    106106    public $Title = '';
    107107    public $Important = false;
     108    public $isAtRule = false;
     109    public $subSections = [];
    108110
    109111    public function __construct($selector, $defaults=array(), $id='', $type='', $help='', $ref='', $important=array())
     
    118120        $this->Title = '';
    119121        $this->Important = $important;
     122        $this->isAtRule = \substr($selector, 0, 1) === '@';
    120123    }
    121124
     
    164167    }
    165168
    166     public function toString()
     169    public function toString(string $indent='')
    167170    {
    168171        $str = '';
     
    181184                $str .= "$k:$v;";
    182185        }
    183         $css = $this->Selector . '{' . $str . '}';
     186        foreach ($this->subSections as $subSection) {
     187            $str .= $subSection->toString($indent . "\t");
     188        }
     189
     190        $css = $indent . $this->Selector;
     191        $css .= ($this->subSections ? " {\n" : '{');
     192        $css .= $str;
     193        $css .= ($this->subSections ? " \n{$indent}}" : '}');
     194
    184195        if( $this->Type == 'button' )
    185196        {
    186             $css .= "\n" . $this->Selector . ':hover{' . $hover . '}';
    187             $css .= "\n" . $this->Selector . ':active{' . $active . '}';
    188         }
    189         return $css;
     197            $css .= "\n" . $indent . $this->Selector . ':hover{' . $hover . '}';
     198            $css .= "\n" . $indent . $this->Selector . ':active{' . $active . '}';
     199        }
     200        return $css . "\n";
     201    }
     202
     203    public function flatten()
     204    {
     205        foreach ($this->subSections as &$subSection) $subSection->flatten();
     206        $this->subSections = \array_values($this->subSections);
    190207    }
    191208}
     
    328345
    329346    /** @return array of Balise
    330      * @param $textDomain the text-domain of the current plugin for translation,
     347     * @param string $textDomain the text-domain of the current plugin for translation,
    331348     * let it false to do not care about titles. */
    332349    public function extract($url, $textDomain=false, $loadValues=true)
     
    360377    public function getBalises()
    361378    {
     379        foreach ($this->Sections as $section) $section->flatten();
    362380        return $this->Sections;
    363381    }
     
    393411    }
    394412
    395     /** @param $addUnknown if true and a selector is unknown in this, then it is added; if false, it is ignored.  */
     413    /** @param bool $addUnknown not used  */
    396414    public function merge($pseudocss, $addUnknown=true)
    397415    {
     
    414432
    415433    /** load the traduction array or generate it if possible.
    416      * @param string textDomain the text-domain of the current plugin for translation. */
     434     * @param string $textDomain the text-domain of the current plugin for translation. */
    417435    public function prepareTitles($textDomain)
    418436    {
     
    644662    protected function build($buffer)
    645663    {
    646         $pos = 0;
    647         $bufferLen = strlen($buffer);
    648         $match = array();
    649 
    650         while( preg_match('/([^\s][^\{]*){/Us', $buffer, $match, PREG_OFFSET_CAPTURE, $pos) )
    651         {
     664        try {
     665            $pos = 0;
     666            $this->Sections = \array_merge($this->Sections, $this->_build($buffer, $pos));
     667        } catch (\Exception $e) {
     668            error_log($e->getMessage());
     669            return false;
     670        }
     671        return true;
     672    }
     673
     674    /**
     675     * @throws \Exception
     676     */
     677    protected function _build(string $buffer, int &$pos): array
     678    {
     679        $flat = [];
     680        $match = [];
     681        $startPattern = '/([^\s][^\{]*){/Us';
     682        $endPattern = '/((?:[^\}\'"]|(?:"(?:[^"\\\\]|\\\\.)*")|(?:\'(?:[^\'\\\\]|\\\\.)*\'))*)(?:\}|$)/Us';
     683
     684        while( preg_match($startPattern, $buffer, $match, PREG_OFFSET_CAPTURE, $pos) )
     685        {
     686            $selector = trim($match[1][0]);
     687
     688            if (\substr($selector, 0, 1) === '}') {
     689                // end of media query
     690                $shift = strlen($selector) - \strlen(ltrim(substr($selector, 1)));
     691                $pos += $shift;
     692                return $flat;
     693            }
     694
     695            // move cursor after the selector
    652696            $pos = strlen($match[0][0]) + $match[0][1];
    653             $selector = trim($match[1][0]);
    654 
    655             if( preg_match('/((?:[^\}\'"]|(?:"(?:[^"\\\\]|\\\\.)*")|(?:\'(?:[^\'\\\\]|\\\\.)*\'))*)(?:\}|$)/Us', $buffer, $match, PREG_OFFSET_CAPTURE, $pos) )
    656             {
     697
     698            if (\substr($selector, 0, 1) === '@') {
     699                // start of media query, look inside
     700                $media = new CSSSection($selector);
     701                $media->subSections = $this->_build($buffer, $pos);
     702                $flat[$selector] = $media;
     703
     704            } elseif (preg_match($endPattern, $buffer, $match, PREG_OFFSET_CAPTURE, $pos) ) {
     705                // css properties
    657706                $pos = strlen($match[0][0]) + $match[0][1];
    658                 $this->readCSSSection($selector, $match[1][0]);
    659             }
    660             else
    661             {
    662                 error_log("Cannot find selector property end '}' in:{$this->Url}\nafter :\n$selector {" . substr($buffer, $pos-1, 128));
    663                 return false;
    664             }
    665         }
    666         return true;
     707                $props = $this->extractProps($match[1][0], $selector);
     708                if ($props) {
     709                    if (isset($flat[$props->uid])) {
     710                        $flat[$props->uid]->merge($props->props, $props->type, $props->help, $props->ref, $props->important);
     711                    } else {
     712                        $flat[$props->uid] = new CSSSection($selector, $props->props, $props->id, $props->type, $props->help, $props->ref, $props->important);
     713                    }
     714                }
     715            } else {
     716                throw new \Exception("Cannot find selector property end '}' in:{$this->Url}\nafter :\n$selector {" . substr($buffer, $pos-1, 128));
     717            }
     718        }
     719        return $flat;
    667720    }
    668721
    669722    /** harvest properties in a CSS section */
    670     protected function readCSSSection($selector, $section)
     723    private function extractProps($section, $selector)
    671724    {
    672725        $props = $this->cssPropsToArray($section);
    673         if( !empty($props) )
    674         {
    675             $id = '';
    676             $help = '';
    677             $type = '';
    678             $ref = '';
    679             $important = array();
    680             foreach( $props as $k => &$v )
    681             {
    682                 if( $k == '$id' )
    683                     $id = $v;
    684                 else if( $k == '$type' )
    685                     $type = $v;
    686                 else if( $k == '$help' )
    687                     $help = $v;
    688                 else if( $k == '$ref' )
    689                     $ref = $v;
    690                 else if( substr($v, -10) === '!important' )
    691                 {
    692                     $important[] = $k;
    693                     $v = trim(substr($v, 0, strlen($v)-10));
    694                 }
    695             }
    696             $uid = $this->MasterID . "$type-" . preg_replace('/[^[:alnum:]_-]/i', '_', urlencode(empty($id)?$selector:$id));
    697             if( array_key_exists($uid, $this->Sections) )
    698                 $this->Sections[$uid]->merge($props, $type, $help, $ref, $important);
    699             else
    700                 $this->Sections[$uid] = new CSSSection($selector, $props, $id, $type, $help, $ref, $important);
    701         }
     726        if (!$props) return false;
     727        $data = (object) [
     728            'props'     => $props,
     729            'id'        => '',
     730            'help'      => '',
     731            'type'      => '',
     732            'ref'       => '',
     733            'important' => [],
     734            '$uid'      => '',
     735        ];
     736        foreach ($props as $k => &$v) {
     737            if( $k == '$id' ) $data->id = $v;
     738            else if( $k == '$type' ) $data->type = $v;
     739            else if( $k == '$help' ) $data->help = $v;
     740            else if( $k == '$ref' ) $data->ref = $v;
     741            else if( substr($v, -10) === '!important' ) {
     742                $data->important[] = $k;
     743                $v = trim(substr($v, 0, strlen($v)-10));
     744            }
     745        }
     746        $data->uid = $this->MasterID . $data->type . '-' . preg_replace('/[^[:alnum:]_-]/i', '_', urlencode($data->id ?: $selector));
     747        return $data;
    702748    }
    703749
     
    845891            if( !empty($balise->Ref) && array_key_exists($balise->Ref, $refs) )
    846892                $balise->mergeValues($refs[$balise->Ref]);
    847             $css .= $balise->toString() . "\n";
     893            $css .= $balise->toString();
    848894        }
    849895        return $css;
  • woorewards/trunk/assets/lws-adminpanel/js/controls/stygen/stygen.js

    r3188612 r3397996  
    1 (function($){$.widget("lws.lws_css_editor",{_create:function(){this.cssValues=lwsBase64.toObj(this.element.data('cssvalues'));this.defaultValues=lwsBase64.toObj(this.element.data('dftvalues'));this.menuTable={};this.cssObject={};this.miscValues={};this.cssChain="";this._createCssObject(this.cssValues);this._createMaster();this._addBackgroundSwitcher();this._setCssEditor();var centralDiv=this.element.find(".lwss_centraldiv");this.popupShadow=$("<div>").addClass("lwss-popup-shadow").appendTo(centralDiv);this.element.on("mouseover",".lwss_menu_selector",this._bind(this._overSelector,this));this.element.on("mouseover",".lwss_selector",this._bind(this._overSelector,this));this.element.on("mouseout",".lwss_menu_selector",this._bind(this._outSelector,this));this.element.on("mouseout",".lwss_selector",this._bind(this._outSelector,this));this.element.on("click",".lwss_menu_selector",this._bind(this._clickSelector,this));this.element.on("click",".lwss_selector",this._bind(this._clickSelector,this));this.element.on("click",".lwss-main-conteneur",this._bind(this._clickEditor,this));this.element.on("click",".lwss-sidemenu",this._bind(this._clickEditor,this));this.element.on("click",".lwss-btvisual",this._bind(this._switchToVisual,this));this.element.on("click",".lwss-btcss",this._bind(this._switchToCss,this));this.element.on("click",".lwss-reset",this._bind(this._resetCss,this));this.myStylingPanel=$("<div>").addClass("lwss_styling_panel").prependTo(centralDiv);this.myStylingPanel.lws_styling_panel({stygen:this});this._createCssResetList();this.makeCssChain()},_bind:function(fn,me){return function(){return fn.apply(me,arguments)}},_createMaster:function(){var me=this;this.masterObject={};var myMenu=this.element.find(".lwss_sidemenu");var elements=this.element.find(".lwss-visual-conteneur");elements=elements.find("[data-selector], .lwss_selectable");elements.each(function(){var mySelectable=$(this);var myClass='';if(mySelectable.data('selector')!=undefined){mySelectable.css('position','relative');myClass=mySelectable.data('selector').trim()}
     1(function($){$.widget("lws.lws_css_editor",{_create:function(){this.cssValues=lwsBase64.toObj(this.element.data('cssvalues'));this.defaultValues=lwsBase64.toObj(this.element.data('dftvalues'));this.tagRules=[];this.menuTable={};this.cssObject={};this.miscValues={};this.cssChain="";this._createCssObject(this.cssValues);this._createMaster();this._addBackgroundSwitcher();this._setCssEditor();var centralDiv=this.element.find(".lwss_centraldiv");this.popupShadow=$("<div>").addClass("lwss-popup-shadow").appendTo(centralDiv);this.element.on("mouseover",".lwss_menu_selector",this._bind(this._overSelector,this));this.element.on("mouseover",".lwss_selector",this._bind(this._overSelector,this));this.element.on("mouseout",".lwss_menu_selector",this._bind(this._outSelector,this));this.element.on("mouseout",".lwss_selector",this._bind(this._outSelector,this));this.element.on("click",".lwss_menu_selector",this._bind(this._clickSelector,this));this.element.on("click",".lwss_selector",this._bind(this._clickSelector,this));this.element.on("click",".lwss-main-conteneur",this._bind(this._clickEditor,this));this.element.on("click",".lwss-sidemenu",this._bind(this._clickEditor,this));this.element.on("click",".lwss-btvisual",this._bind(this._switchToVisual,this));this.element.on("click",".lwss-btcss",this._bind(this._switchToCss,this));this.element.on("click",".lwss-reset",this._bind(this._resetCss,this));this.myStylingPanel=$("<div>").addClass("lwss_styling_panel").prependTo(centralDiv);this.myStylingPanel.lws_styling_panel({stygen:this});this._createCssResetList();this.makeCssChain()},_bind:function(fn,me){return function(){return fn.apply(me,arguments)}},_createMaster:function(){var me=this;this.masterObject={};var myMenu=this.element.find(".lwss_sidemenu");var elements=this.element.find(".lwss-visual-conteneur");elements=elements.find("[data-selector], .lwss_selectable");elements.each(function(){var mySelectable=$(this);var myClass='';if(mySelectable.data('selector')!=undefined){mySelectable.css('position','relative');myClass=mySelectable.data('selector').trim()}
    22if(0==myClass.length)
    33myClass="."+mySelectable.attr("class").trim().replace(/\s+/g,".");var myStylableObject={Selectable:mySelectable,Selector:me._createSelector(mySelectable,myClass),Class:myClass,Over:"no",Active:"no"};if(me.masterObject[myClass]==undefined){me.masterObject[myClass]={};me.masterObject[myClass].elements=[];me.masterObject[myClass].cssValues=(me.cssObject[myClass]!=undefined)?me.cssObject[myClass]:{'idle':{}};if(me.cssObject[myClass]==undefined){me.cssObject[myClass]=me.masterObject[myClass].cssValues}
     
    1414var blackSwitcher=$("<div>").addClass("lws-black-switcher").appendTo(bgSwitcher);blackSwitcher.on('click',function(){main.css("background","#000000")})},placeSelectors:function(){this.element.find('.lwss_inp_sel').each(function(){var theSelector=$(this);var theSelectable=theSelector.parent().find('.lwss_selectable');theSelector.outerWidth(theSelectable.outerWidth(!0)+4).outerHeight(theSelectable.outerHeight(!0)+4);theSelector.css('top',theSelectable.position().top-2).css('left',theSelectable.position().left-2)})},_clickSelector:function(event){this.element.find('.lwss_selector').removeClass('lwss_sel_sel');this.element.find('.lwss_menu_selector').removeClass('lwss_sel_msel');var theClass=$(event.currentTarget).data("theClass")
    1515var current=this.masterObject[theClass];current.menuItem.addClass('lwss_sel_msel');for(let i=0;i<current.elements.length;i++){current.elements[i].Selector.addClass('lwss_sel_sel')}
    16 var currentItem=this.masterObject[theClass].elements[0].Selectable;var inputId=(currentItem.data('id')!='')?currentItem.data('id'):'';this.element.find(".lwss_info").hide();this.myStylingPanel.lws_styling_panel("openStylingPanel",theClass,inputId,currentItem);this.myStylingPanel.show();event.preventDefault();return!1},_clickEditor:function(event){var element=($(event.target).hasClass('lwss_menu_selector_text')||$(event.target).hasClass('lwss_menu_selector_text'))?$(event.target.parentElement):$(event.target);if(!element.hasClass('lwss_selector')&&!element.hasClass('lwss_menu_selector')){this.element.find('.lwss_selector').removeClass('lwss_sel_sel');this.element.find('.lwss_menu_selector').removeClass('lwss_sel_msel');this.myStylingPanel.lws_styling_panel("setEvent",'idle');this.element.find(".lwss_styling_panel").hide();this.element.find(".lwss_info").show()}},_updateMaster:function(){var me=this;$.each(this.cssObject,function(className,element){$.each(element,function(statekey,statevalues){if(me.masterObject[className]!=undefined){me.masterObject[className].cssValues[statekey]=statevalues}})})},_resetCss:function(){this.cssObject={};this._createCssObject(this.defaultValues);this._updateMaster();this._applyCssObject();this.makeCssChain();if(this.cssEditor!=undefined)this.cssEditor.codemirror.setValue(this.cssChain);},_editorCssChanged:function(){var nbErrors=this.cssConteneur.find('.CodeMirror-lint-marker-error').length;if(nbErrors==0&&this.cssEditor!=undefined){this._cleanStyleObjects();var cssContent=this.cssEditor.codemirror.getValue();var wip=cssContent.replace(/(?:\r\n|\r|\n|\t)/g,'');wip=wip.split('}');for(var i=0;i<wip.length;i++){if(wip[i]!=''){var line=wip[i].split('{');var lselector=line[0].split(':');var myClass=lselector[0].trim();var stateClass=(lselector[1]==undefined)?'idle':lselector[1].trim();var cssValTable=line[1].split(';');var cssValues={}
    17 for(var j=0;j<cssValTable.length;j++){if(cssValTable[j].indexOf(':')!=-1){cssValues[cssValTable[j].split(':')[0].trim()]=cssValTable[j].split(':')[1].trim()}}
    18 this.cssObject[myClass]={};this.cssObject[myClass][stateClass]=cssValues}}
    19 this._updateMaster();this._applyCssObject();this.makeCssChain()}},_applyCssObject:function(){$.each(this.cssObject,function(className,element){$.each(element,function(statekey,statevalues){lwssCanvas.find(className).css(statevalues)})})},_cleanStyleObjects:function(){$.each(this.masterObject,function(className,element){element.cssValues={}})
    20 this.cssObject={}},_createCssObject:function(sourceValues){var me=this;lwssCanvas=this.element;$.each(sourceValues,function(index,element){element.Selector=element.Selector.replaceAll('::',':');var mainClass=(element.Selector.split(":"))[0];var event=((element.Selector.split(",")[0].split(":"))[1]!=undefined)?(element.Selector.split(",")[0].split(":"))[1]:"idle";var myClass=(me.cssObject[mainClass]!=undefined)?me.cssObject[mainClass]:{};myClass[event]=element.Defaults;if(element.Values!=null&&element.Values!=undefined&&!Array.isArray(element.Values)){myClass[event]=element.Values}
    21 me.cssObject[mainClass]=myClass;lwssCanvas.find(element.Selector).css(element.Defaults);lwssCanvas.find(element.Selector).css(element.Values)})},makeCssChain:function(){lwssCanvas=this.element;this.cssChain="";var me=this;var theInput=this.element.find(".lwss_editor_chain");var pseudoElements=['after','backdrop','before','cue','first-letter','first-line','grammar-error','marker','part','placeholder','selection','slotted','spelling-error'];$.each(this.cssObject,function(className,element){$.each(element,function(statekey,statevalues){if(statevalues!=''){if(statekey=="idle"){me.cssChain+=className+"{"}else if(statekey=="hover"){me.cssChain+=className+":hover, "+className+".hovered{"}else if(statekey=="focus"){me.cssChain+=className+":focus, "+className+".focused{"}else{me.cssChain+=className+":";if(pseudoElements.includes(statekey))
    22 me.cssChain+=":";me.cssChain+=statekey+"{"}
    23 $.each(statevalues,function(csskey,cssvalue){if(cssvalue!=undefined&&cssvalue!='')me.cssChain+=csskey+":"+cssvalue+";"});me.cssChain+="}\n"}})});theInput.val(lwsBase64.encode(this.cssChain))},})})(jQuery)
     16var currentItem=this.masterObject[theClass].elements[0].Selectable;var inputId=(currentItem.data('id')!='')?currentItem.data('id'):'';this.element.find(".lwss_info").hide();this.myStylingPanel.lws_styling_panel("openStylingPanel",theClass,inputId,currentItem);this.myStylingPanel.show();event.preventDefault();return!1},_clickEditor:function(event){var element=($(event.target).hasClass('lwss_menu_selector_text')||$(event.target).hasClass('lwss_menu_selector_text'))?$(event.target.parentElement):$(event.target);if(!element.hasClass('lwss_selector')&&!element.hasClass('lwss_menu_selector')){this.element.find('.lwss_selector').removeClass('lwss_sel_sel');this.element.find('.lwss_menu_selector').removeClass('lwss_sel_msel');this.myStylingPanel.lws_styling_panel("setEvent",'idle');this.element.find(".lwss_styling_panel").hide();this.element.find(".lwss_info").show()}},_updateMaster:function(){var me=this;$.each(this.cssObject,function(className,element){$.each(element,function(statekey,statevalues){if(me.masterObject[className]!=undefined){me.masterObject[className].cssValues[statekey]=statevalues}})})},_cleanStyles:function(){$.each(this.cssObject,function(className,element){try{lwssCanvas.find(className).removeAttr('style')}catch(e){}})},_resetCss:function(){this._cleanStyles();this.cssObject={};this.tagRules=[];this._createCssObject(this.defaultValues);this._updateMaster();this._applyCssObject();this.makeCssChain();if(this.cssEditor!=undefined)this.cssEditor.codemirror.setValue(this.cssChain);},_parseCss:function(text){const startPattern=/(\S[^{]*)\{/s;const endPattern=/((?:[^}'"]|(?:"(?:[^"\\\\]|\\\\.)*")|(?:'(?:[^'\\\\]|\\\\.)*'))*)(?:}|$)/s;let cursor={text:text,sections:[]};let selector=cursor.text.match(startPattern);while(selector!==null&&cursor.text.length>0){cursor.text=cursor.text.substring(selector[0].length).trimStart();let element={Selector:selector[1],isAtRule:selector[0].startsWith('@'),Help:'',ID:'',Important:[],Ref:'',Title:'',Type:'',Defaults:{},Values:[],subSections:[]}
     17if(element.isAtRule){let result=this._parseCss(cursor.text);element.subSections=result.sections;cursor.text=result.text;selector=cursor.text.match(startPattern)}
     18let content=cursor.text.match(endPattern);if(content!==null){cursor.text=cursor.text.substring(content[0].length).trimStart();selector=cursor.text.match(startPattern)}else{content=['',cursor.text];selector=null;cursor.text=''}
     19let props=content[1].trim().split(';');for(let line of props){let sep=line.indexOf(':');if(sep!==-1){let prop=line.substring(0,sep).trim();element.Defaults[prop]=line.substring(sep+1).trim()}}
     20cursor.sections.push(element);if(cursor.text.startsWith('}'))break}
     21return cursor},_editorCssChanged:function(){var nbErrors=this.cssConteneur.find('.CodeMirror-lint-marker-error').length;if(nbErrors===0&&this.cssEditor!=undefined){this._cleanStyleObjects();var cssContent=this.cssEditor.codemirror.getValue().replace(/\r\n|\r|\n|\t/g,'');this._createCssObject(this._parseCss(cssContent.trim()).sections);this._updateMaster();this._applyCssObject();this.makeCssChain()}},_applyCssObject:function(){$.each(this.cssObject,function(className,element){try{$.each(element,function(stateKey,stateValues){lwssCanvas.find(className).css(stateValues)})}catch(e){console.log('Update: Invalid css near ',element)}})},_cleanStyleObjects:function(){this._cleanStyles();$.each(this.masterObject,function(className,element){element.cssValues={}})
     22this.cssObject={};this.tagRules=[]},_createCssObject:function(sourceValues){var me=this;lwssCanvas=this.element;$.each(sourceValues,function(index,element){try{if(element.isAtRule){me.tagRules.push(element)}else{element.Selector=element.Selector.replaceAll('::',':');var mainClass=(element.Selector.split(":"))[0];var event=((element.Selector.split(",")[0].split(":"))[1]!=undefined)?(element.Selector.split(",")[0].split(":"))[1]:"idle";var myClass=(me.cssObject[mainClass]!=undefined)?me.cssObject[mainClass]:{};myClass[event]=element.Defaults;if(element.Values!=null&&element.Values!=undefined&&!Array.isArray(element.Values)){myClass[event]=element.Values}
     23me.cssObject[mainClass]=myClass;lwssCanvas.find(element.Selector).css(element.Defaults);lwssCanvas.find(element.Selector).css(element.Values)}}catch(e){console.log(e);console.log('Setup: Invalid css near ',element)}})},compileTagRules:function(tagRules,self,indent){let chain='';if(undefined===self)self=this;if(undefined===indent)indent='';$.each(tagRules,function(className,element){if(element.isAtRule){chain+=indent+element.Selector+"{\n";chain+=self.compileTagRules(element.subSections,self,indent+"\t");chain+=indent+"}\n"}else{chain+=indent+element.Selector+"{";$.each(element.Defaults,function(prop,values){chain+=prop+': '+values+';'});chain+='}'}});return chain},compileCss:function(cssObject){let chain='';const pseudoElements=['after','backdrop','before','cue','first-letter','first-line','grammar-error','marker','part','placeholder','selection','slotted','spelling-error'];$.each(cssObject,function(className,element){$.each(element,function(stateKey,stateValues){if(stateValues!==''){if(stateKey==="idle"){chain+=className+"{"}else if(stateKey==="hover"){chain+=className+":hover, "+className+".hovered{"}else if(stateKey==="focus"){chain+=className+":focus, "+className+".focused{"}else{chain+=className+":";if(pseudoElements.includes(stateKey))
     24chain+=":";chain+=stateKey+"{"}
     25$.each(stateValues,function(cssKey,cssValue){if(cssValue!==undefined&&cssValue!=='')chain+=cssKey+":"+cssValue+";"});chain+="}\n"}})});return chain},makeCssChain:function(){this.cssChain=this.compileCss(this.cssObject)+this.compileTagRules(this.tagRules);this.element.find(".lwss_editor_chain").val(lwsBase64.encode(this.cssChain))},})})(jQuery)
    2426jQuery(function($){$(".lwss_editor").lws_css_editor();$(".lwss_editor").on('click',function(e){if($(e.target).closest(".lwss-color-selector-relative").length==0&&$(e.target).closest(".lwss-fontselect-popup").length==0)
    2527$(".lwss-popup-shadow").hide();})})
  • woorewards/trunk/assets/lws-adminpanel/languages/lws-adminpanel-fr_FR.po

    r3188612 r3397996  
    12481248
    12491249#~ msgid "Deactivate my license"
    1250 #~ msgstr "Activer votre licence"
     1250#~ msgstr "Désactiver votre licence"
    12511251
    12521252#~ msgid "Activate license"
  • woorewards/trunk/assets/lws-adminpanel/lws-adminpanel.php

    r3350120 r3397996  
    66 * Author: Long Watch Studio
    77 * Author URI: https://longwatchstudio.com
    8  * Version: 5.6.6
     8 * Version: 5.6.7
    99 * Text Domain: lws-adminpanel
    1010 *
     
    5858
    5959add_filter('lws_adminpanel_versions', function($versions){
    60     $versions['5.6.6'] = __FILE__;
     60    $versions['5.6.7'] = __FILE__;
    6161    return $versions;
    6262});
  • woorewards/trunk/build/style-index-rtl.css

    r3188612 r3397996  
    1 .wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold{text-decoration:none;cursor:pointer;color:inherit;display:flex;margin:0px 16px;border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11)}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold svg{margin-right:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component{border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11);margin-top:16px;padding:8px 16px}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component.is_loading{opacity:.5}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold{display:flex;gap:8px;cursor:pointer}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold svg{margin-right:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form{display:flex;flex-direction:row;gap:8px;margin-bottom:0;width:100%}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form>*{margin-top:0px}@keyframes dot-flashing{0%{bottom:0px}25%{bottom:10px}46%{bottom:-3px}50%,100%{bottom:0px}}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots span{opacity:1;font-weight:bold;position:relative;animation-timing-function:ease-in-out;animation:dot-flashing 2s infinite}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot1{animation-delay:0s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot2{animation-delay:.5s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot3{animation-delay:1s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button{cursor:pointer;align-items:center;display:inline-flex;flex:1;height:auto;justify-content:center;position:relative;text-align:center;transition:box-shadow .1s linear;padding-right:1em;padding-left:1em}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button:disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.wc-block-components-totals-wrapper .lws-wr-blocks .points-on-cart-details{font-size:smaller;font-weight:bold;text-align:left;display:inline-block;width:100%}
     1.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold{text-decoration:none;cursor:pointer;color:inherit;display:flex;flex-direction:row;margin:0px 16px;border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11)}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold .wr-label{display:flex;justify-content:space-between;flex-grow:1}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold svg{margin-right:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component{border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11);margin-top:16px;padding:8px 16px}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component.is_loading{opacity:.5}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold{display:flex;gap:8px;cursor:pointer}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold svg{margin-right:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form{display:flex;flex-direction:row;gap:8px;margin-bottom:0;width:100%}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form>*{margin-top:0px}@keyframes dot-flashing{0%{bottom:0px}25%{bottom:10px}46%{bottom:-3px}50%,100%{bottom:0px}}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots span{opacity:1;font-weight:bold;position:relative;animation-timing-function:ease-in-out;animation:dot-flashing 2s infinite}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot1{animation-delay:0s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot2{animation-delay:.5s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot3{animation-delay:1s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button{cursor:pointer;align-items:center;display:inline-flex;flex:1;height:auto;justify-content:center;position:relative;text-align:center;transition:box-shadow .1s linear;padding-right:1em;padding-left:1em}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button:disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.wc-block-components-totals-wrapper .lws-wr-blocks .points-on-cart-details{font-size:smaller;font-weight:bold;text-align:left;display:inline-block;width:100%}
  • woorewards/trunk/build/style-index.css

    r3188612 r3397996  
    1 .wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold{text-decoration:none;cursor:pointer;color:inherit;display:flex;margin:0px 16px;border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11)}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold svg{margin-left:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component{border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11);margin-top:16px;padding:8px 16px}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component.is_loading{opacity:.5}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold{display:flex;gap:8px;cursor:pointer}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold svg{margin-left:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form{display:flex;flex-direction:row;gap:8px;margin-bottom:0;width:100%}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form>*{margin-top:0px}@keyframes dot-flashing{0%{bottom:0px}25%{bottom:10px}46%{bottom:-3px}50%,100%{bottom:0px}}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots span{opacity:1;font-weight:bold;position:relative;animation-timing-function:ease-in-out;animation:dot-flashing 2s infinite}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot1{animation-delay:0s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot2{animation-delay:.5s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot3{animation-delay:1s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button{cursor:pointer;align-items:center;display:inline-flex;flex:1;height:auto;justify-content:center;position:relative;text-align:center;transition:box-shadow .1s linear;padding-left:1em;padding-right:1em}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button:disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.wc-block-components-totals-wrapper .lws-wr-blocks .points-on-cart-details{font-size:smaller;font-weight:bold;text-align:right;display:inline-block;width:100%}
     1.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold{text-decoration:none;cursor:pointer;color:inherit;display:flex;flex-direction:row;margin:0px 16px;border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11)}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold .wr-label{display:flex;justify-content:space-between;flex-grow:1}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component_unfold svg{margin-left:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component{border-top:1px solid rgba(18,18,18,.11);border-bottom:1px solid rgba(18,18,18,.11);margin-top:16px;padding:8px 16px}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component.is_loading{opacity:.5}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold{display:flex;gap:8px;cursor:pointer}.wc-block-components-totals-wrapper .lws-wr-blocks.pointsoncart-component .pointsoncart-component_fold svg{margin-left:auto;fill:currentColor}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form{display:flex;flex-direction:row;gap:8px;margin-bottom:0;width:100%}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form>*{margin-top:0px}@keyframes dot-flashing{0%{bottom:0px}25%{bottom:10px}46%{bottom:-3px}50%,100%{bottom:0px}}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots span{opacity:1;font-weight:bold;position:relative;animation-timing-function:ease-in-out;animation:dot-flashing 2s infinite}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot1{animation-delay:0s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot2{animation-delay:.5s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form .loading-dots .dot3{animation-delay:1s}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button{cursor:pointer;align-items:center;display:inline-flex;flex:1;height:auto;justify-content:center;position:relative;text-align:center;transition:box-shadow .1s linear;padding-left:1em;padding-right:1em}.wc-block-components-totals-wrapper .lws-wr-blocks .pointsoncart-component_form button:disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.wc-block-components-totals-wrapper .lws-wr-blocks .points-on-cart-details{font-size:smaller;font-weight:bold;text-align:right;display:inline-block;width:100%}
  • woorewards/trunk/include/abstracts/collection.php

    r3188612 r3397996  
    161161    public static function getNewName($proposal='untitled', $existants=array())
    162162    {
     163        $existants = \array_filter((array)$existants);
    163164        if( empty($existants) )
    164165            return $proposal;
  • woorewards/trunk/include/core/pointstack.php

    r3188612 r3397996  
    290290
    291291        if ( $timezone_string ) {
    292                 return $timezone_string;
     292            return $timezone_string;
    293293        }
    294294
     
    391391        }
    392392        return $history;
     393    }
     394
     395    /**
     396     * Retrieve history for multiple stacks in a single query
     397     * @param int $userId
     398     * @param array $stackNames Array of stack names
     399     * @param int $offset
     400     * @param int $limit
     401     * @param bool $translate
     402     * @return array Grouped by stack name
     403     */
     404    public static function getHistoryBulk($userId, $stackNames, $offset = 0, $limit = 15, $translate = true)
     405    {
     406        global $wpdb;
     407
     408        if (empty($stackNames)) {
     409            return array();
     410        }
     411
     412        $placeholders = implode(',', array_fill(0, count($stackNames), '%s'));
     413        $sql = "
     414        SELECT
     415            id,
     416            mvt_date as op_date,
     417            points_moved as op_value,
     418            new_total as op_result,
     419            commentar as op_reason,
     420            origin,
     421            stack
     422        FROM {$wpdb->lwsWooRewardsHistoric}
     423        WHERE user_id = %d AND stack IN ($placeholders)
     424        ORDER BY mvt_date DESC, id DESC
     425        LIMIT %d OFFSET %d
     426    ";
     427
     428        $args = array_merge(
     429            array($userId),
     430            $stackNames,
     431            array($limit, $offset)
     432        );
     433
     434        $history = $wpdb->get_results($wpdb->prepare($sql, $args), ARRAY_A);
     435
     436        if ($translate && $history) {
     437            $pools = array();
     438            foreach ($stackNames as $stackName) {
     439                $pool = \apply_filters('lws_woorewards_get_pools_by_stack', false, $stackName);
     440                $pools[$stackName] = $pool ? $pool->sort()->first() : false;
     441            }
     442
     443            $originIds = array_filter(
     444                array_column($history, 'origin'),
     445                function($val) { return $val && \is_numeric($val); }
     446            );
     447            $originTitles = !empty($originIds) ? self::bulkGetOriginTitles($originIds) : array();
     448
     449            foreach ($history as &$row) {
     450                $pool = $pools[$row['stack']] ?? false;
     451
     452                if ($pool) {
     453                    if (\is_numeric($row['op_value'])) {
     454                        $row['op_value'] = $pool->formatPoints($row['op_value'], false);
     455                    }
     456                    if (\is_numeric($row['op_result'])) {
     457                        $row['op_result'] = $pool->formatPoints($row['op_result'], false);
     458                    }
     459                }
     460
     461                if ($row['origin'] && ($originTitles[$row['origin']] ?? false)) {
     462                    $row['op_reason'] = $originTitles[$row['origin']];
     463                } elseif ($row['op_reason'] && \is_serialized($row['op_reason'])) {
     464                    $reason = @unserialize($row['op_reason']);
     465                    if ($reason && is_array($reason)) {
     466                        $row['op_reason'] = \LWS\WOOREWARDS\Core\Trace::reasonToString($reason, true);
     467                    }
     468                }
     469            }
     470        }
     471
     472        return $history;
     473    }
     474
     475    protected static function bulkGetOriginTitles($originIds)
     476    {
     477        static $replaceReason = null;
     478        if (null === $replaceReason) {
     479            $replaceReason = \apply_filters('lws_woorewards_stack_history_prefers_origin_title', true);
     480        }
     481
     482        $titles = array();
     483        if (!$replaceReason) {
     484            return $titles;
     485        }
     486
     487        global $wpdb;
     488        $placeholders = implode(',', array_fill(0, count($originIds), '%d'));
     489        $sql = "SELECT ID, post_type FROM {$wpdb->posts} WHERE ID IN ($placeholders)";
     490
     491        $results = $wpdb->get_results(
     492            $wpdb->prepare($sql, $originIds),
     493            OBJECT_K
     494        );
     495
     496        foreach ($results as $id => $row) {
     497            $object = null;
     498            $post = \get_post($id);
     499            if (!$post) {
     500                continue;
     501            }
     502
     503            if ($row->post_type === \LWS\WOOREWARDS\Abstracts\Event::POST_TYPE) {
     504                $object = \LWS\WOOREWARDS\Abstracts\Event::fromPost($post);
     505            } elseif ($row->post_type === \LWS\WOOREWARDS\Abstracts\Unlockable::POST_TYPE) {
     506                $object = \LWS\WOOREWARDS\Abstracts\Unlockable::fromPost($post);
     507            }
     508
     509            if ($object) {
     510                $title = $object->getTitleAsReason();
     511                if ($title) {
     512                    $titles[$id] = $title;
     513                }
     514            }
     515        }
     516
     517        return $titles;
    393518    }
    394519
  • woorewards/trunk/include/pointdiscount.php

    r3227529 r3397996  
    1818        \add_filter('woocommerce_cart_totals_coupon_label', array($me, 'asLabel'), 20, 2);
    1919        \add_filter('woocommerce_order_item_get_code', array($me, 'asCode'), 20, 2);
     20        \add_filter('woocommerce_order_recalculate_coupons_coupon_object', [$me, 'asOriginal'], 10, 4);
    2021        //\add_filter('woocommerce_coupon_error', array($me, 'asError'), 20, 3);
    2122        \add_filter('woocommerce_get_shop_coupon_data', array($me, 'asData'), PHP_INT_MAX - 8, 3);
     
    558559    }
    559560
     561    /** @param\WC_Coupon $coupon_object
     562     * @param $coupon_object
     563     * @param string $coupon_code
     564     * @param \WC_Order_Item $coupon_item
     565     * @param $order
     566     *
     567     * @return \WC_Coupon
     568     */
     569    function asOriginal($coupon_object, $coupon_code, $coupon_item, $order) {
     570        $data = $coupon_item->get_meta('wr_discount_data', true, 'edit');
     571        if ($data) {
     572            $coupon_object->add_meta_data( 'wr_discount_data', $data );
     573        }
     574        return $coupon_object;
     575    }
     576
    560577    /** Get a label (instead of raw code) from Order Item */
    561578    function asCode($code, $item)
     
    566583            if ($data)
    567584            {
    568                 return $this->getTitle($data);
     585                $title = $this->getTitle($data);
     586                $formatted = \wc_format_coupon_code($title);
     587                if ($formatted) return $formatted;
    569588            }
    570589        }
  • woorewards/trunk/include/ui/admin.php

    r3350120 r3397996  
    10161016    }
    10171017    /** Tease about pro version.
    1018      * Display standand pool settings. */
     1018     * Display standard pool settings. */
    10191019    protected function getLoyaltyGroups()
    10201020    {
  • woorewards/trunk/include/ui/blocks/integration.php

    r3188612 r3397996  
    99class Integration implements \Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface {
    1010    const API = 'lws_woorewards';
    11     protected $styleHandlers = [];
     11    protected $editionScriptHandlers = [];
    1212    protected $scriptHandlers = [];
    1313
     
    146146                self::version($options['style'])
    147147            );
    148             $this->styleHandlers[$options['style-handle']] = $options['style-handle'];
     148            $this->editionScriptHandlers[$options['style-handle']] = $options['style-handle'];
    149149        }
    150150
     
    175175     * @return string[] */
    176176    public function get_editor_script_handles() {
    177         return $this->styleHandlers;
     177        return $this->editionScriptHandlers;
    178178    }
    179179
  • woorewards/trunk/include/ui/editlists/multiformlist.php

    r3188612 r3397996  
    2222    abstract protected function getStepInfo();
    2323
    24     function __construct(\LWS\WOOREWARDS\Core\Pool $pool=null)
     24    /** @param \LWS\WOOREWARDS\Core\Pool|null $pool */
     25    function __construct($pool=null)
    2526    {
    2627        $this->pool = $pool;
  • woorewards/trunk/include/ui/woocommerce/pointsoncart.php

    r3227529 r3397996  
    463463            'layout'      => 'horizontal',
    464464            'system'      => '',
     465            'shared'      => '',
     466            'force'       => '',
     467            'showall'     => '',
    465468            'reload'      => false,
    466469            'need_points' => false,
     
    473476            $atts['showall'] = true;
    474477        }
    475         $pool = $this->getPool($atts, $userId);
    476         if ($pool) {
     478        $contents = [];
     479        foreach($this->getPools($atts, $userId)->asArray() as $pool) {
     480            $stack = $pool->getStackId();
     481            if (isset($contents[$stack])) continue;
     482
    477483            $info = $this->getInfo($pool);
    478484            if ($info && \LWS\Adminpanel\Tools\Conveniences::argIsTrue($atts['need_points'])) {
     
    481487
    482488            if ($info) {
    483                 return $this->getContent('shortcode', $info, \LWS\Adminpanel\Tools\Conveniences::argIsTrue($atts['reload']), $atts['layout']);
     489                $contents[$stack] = $this->getContent('shortcode', $info, \LWS\Adminpanel\Tools\Conveniences::argIsTrue($atts['reload']), $atts['layout']);
    484490            } else {
    485                 return $this->getPlaceholder($pool, 'shortcode');
     491                $contents[$stack] = $this->getPlaceholder($pool, 'shortcode');
    486492            }
    487493        }
    488         return \do_shortcode((string)$content);
     494
     495        if (empty($contents)) {
     496            return \do_shortcode( (string) $content );
     497        } elseif (1 === \count($contents)) {
     498            return \reset($contents);
     499        } else {
     500            return sprintf(
     501                '<div class="lws-wr-pointsoncart-blocs">%s</div>',
     502                \implode('</div><div class="lws-wr-pointsoncart-blocs">', $contents)
     503            );
     504        }
    489505    }
    490506
     
    527543    }
    528544
    529     protected function getPool($atts, $userId=false)
     545    protected function getPools($atts, $userId=false)
    530546    {
    531547        if( false === $userId )
     
    534550        $pools = \apply_filters('lws_woorewards_get_pools_by_args', false, $atts, $userId);
    535551        if( !$pools )
    536             return false;
    537 
    538         $pools = $pools->filter(array(__CLASS__, 'filterPools'));
    539         return $pools->last();
     552            return new \LWS\WOOREWARDS\Collections\Pools();
     553
     554        return $pools->filter(array(__CLASS__, 'filterPools'));
     555    }
     556
     557    protected function getPool($atts, $userId=false)
     558    {
     559        return $this->getPools($atts, $userId)->last();
    540560    }
    541561
     
    610630        if( !$userId )
    611631            return $content;
    612 
    613         $atts = \wp_parse_args($atts, array('raw' => ''));
    614         $pool = $this->getPool($atts, $userId);
    615 
    616         if( $pool && \WC()->cart )
    617         {
    618             $content = $this->getMaxPoints($pool, \WC()->cart, $userId);
    619             if( !$atts['raw'] )
    620                 $content = \LWS_WooRewards::formatPointsWithSymbol($content, $pool->getName());
    621         }
    622         return $content;
     632        if (!\WC()->cart)
     633            return $content;
     634
     635        $atts = \wp_parse_args($atts, array(
     636            'raw'     => '',
     637      'system'  => '',
     638      'shared'  => '',
     639      'force'   => '',
     640      'showall' => '',
     641        ));
     642        $as_raw = \LWS\Adminpanel\Tools\Conveniences::argIsTrue($atts['raw']);
     643
     644        $points = [];
     645        foreach($this->getPools($atts, $userId)->asArray() as $pool) {
     646            $raw = $this->getMaxPoints($pool, \WC()->cart, $userId);
     647            $points[] = $as_raw ? $raw : \LWS_WooRewards::formatPointsWithSymbol($raw, $pool->getName());
     648        }
     649
     650        if (empty($points)) {
     651            return $content;
     652        } elseif (1 === count($points)) {
     653            return reset($points);
     654        } elseif ($as_raw) {
     655            return \implode(', ', $points);
     656        } else {
     657            return sprintf(
     658                '<div class="lws-wr-max-pointsoncart-values">%s</div>',
     659                \implode('</div><div class="lws-wr-max-pointsoncart-values">', $points)
     660            );
     661        }
    623662    }
    624663
     
    720759            $reload = 'on';
    721760        $header = \lws_get_option('lws_wooreward_points_cart_header', __('Loyalty points discount', 'woorewards-lite'));
    722         $header = \apply_filters('wpml_translate_single_string', $header, 'Widgets', "WooRewards - Points On Cart Action - Header");
     761        if ('_' === $header) {
     762            $header = '';
     763        } else {
     764            $header = \apply_filters( 'wpml_translate_single_string', $header, 'Widgets', "WooRewards - Points On Cart Action - Header" );
     765        }
     766        if ($header) $header = "<h2>{$header}</h2>";
    723767
    724768        $details = implode('', $this->getDetailsText($origin, $info, $poolInfo));
     
    732776        $content = <<<EOT
    733777        <div class='lwss_selectable lws-wr-pointsoncart{$class}{$layout}' data-origin='{$origin}' data-pool='{$esc['pool']}' data-url='{$url}' data-type="Main Container">
    734             <h2>{$header}</h2>
     778            {$header}
    735779            <div class='lwss_selectable lws-wr-cart lws_wr_pointsoncart_contribution' data-type='Inner Container' data-nonce='{$esc['nonce']}' data-url='{$esc['url']}' data-reload='{$reload}'>
    736780                <div class='lwss_selectable wr-cart-balance' data-type='Balance Container'>
  • woorewards/trunk/include/updater.php

    r3377388 r3397996  
    4040    {
    4141        global $wpdb;
     42
     43        $fresh = version_compare($fromVersion, '1.0.0', '<');
    4244
    4345        if( version_compare($fromVersion, '2.6.6', '<') )
     
    135137            }
    136138            self::addV5PrefabEvents();
     139        }
     140
     141        if (!$fresh && version_compare($fromVersion, '5.6.0', '<')) {
     142            self::v560();
    137143        }
    138144
     
    157163    }
    158164
    159     /** @retrun bool merge done successfully */
     165    public static function v560()
     166    {
     167        $option = 'lws_woorewards_history_template';
     168        $css64 = \get_option($option, false);
     169        if ($css64) {
     170            $css = \base64_decode($css64);
     171            $file = LWS_WOOREWARDS_PATH . '/styling/css/templates/userpointshistory.css';
     172            $template = fopen($file, 'r');
     173            if ($template) {
     174                $content = (string)fread($template, filesize($file));
     175                fclose($template);
     176                if ($content) {
     177                    \update_option($option, \base64_encode($content . "\n\n" . $css));
     178
     179                    // revoke cache
     180                    $cacheName = sanitize_key($option) . '-cached.css';
     181                    $cached = new \LWS\Adminpanel\Tools\Cache($cacheName);
     182                    $cached->del();
     183                    \update_option($option . '_adm_ts', time());
     184                }
     185            }
     186        }
     187    }
     188
     189        /** @retrun bool merge done successfully */
    160190    public static function mergeAllHistorics(): bool
    161191    {
  • woorewards/trunk/readme.txt

    r3379313 r3397996  
    55Tested up to: 6.8
    66Requires PHP: 7.3.0
    7 Stable tag: 5.5.2
     7Stable tag: 5.6.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    110110== Changelog ==
    111111
     112= 5.6.0 =
     113* Update - Embedded styling tool supports media query
     114* Feature - Add paging to User points history shortcode
     115* Dev - Add filter to force arbitrary price on free product
     116* Fix - Auto-apply coupon case sensitivity
     117* Fix - Edit WC React cart failed with points on cart
     118* Fix - Points-on-cart Coupon duplication in Order edition page after a status update
     119
     120= 5.5.3 =
     121* Tag - WooCommerce 10.3
     122* Fix - Duplication Points-on-cart coupon on order edition
     123
    112124= 5.5.2 =
    113125* Fix - supports php7.3 again
  • woorewards/trunk/woorewards.php

    r3379313 r3397996  
    77 * Author: Long Watch Studio
    88 * Author URI: https://longwatchstudio.com
    9  * Version: 5.5.2
     9 * Version: 5.6.0
    1010 * License: Copyright LongWatchStudio 2022
    1111 * Text Domain: woorewards-lite
    1212 * Domain Path: /languages
    1313 * WC requires at least: 7.1.0
    14  * WC tested up to: 10.2
     14 * WC tested up to: 10.3
    1515 *
    1616 * Copyright (c) 2022 Long Watch Studio (email: plugins@longwatchstudio.com). All rights reserved.
     
    111111    private function defineConstants()
    112112    {
    113         define('LWS_WOOREWARDS_VERSION', '5.5.2');
     113        define('LWS_WOOREWARDS_VERSION', '5.6.0');
    114114        define('LWS_WOOREWARDS_FILE', __FILE__);
    115115        define('LWS_WOOREWARDS_DOMAIN', 'woorewards-lite');
     
    149149    public function addPluginVersion($url)
    150150    {
    151         return '5.5.2';
     151        return '5.6.0';
    152152    }
    153153
     
    329329        require_once LWS_WOOREWARDS_INCLUDES . '/ui/shortcodes/pointsvalue.php';
    330330        \LWS\WOOREWARDS\Ui\Shortcodes\PointsValue::install();
    331         require_once LWS_WOOREWARDS_INCLUDES . '/ui/shortcodes/userhistory.php';
    332         \LWS\WOOREWARDS\Ui\Shortcodes\UserHistory::install();
     331        require_once LWS_WOOREWARDS_INCLUDES . '/ui/shortcodes/userpointshistory.php';
     332        \LWS\WOOREWARDS\Ui\Shortcodes\UserPointsHistory::install();
    333333
    334334        require_once LWS_WOOREWARDS_INCLUDES . '/pointdiscount.php';
Note: See TracChangeset for help on using the changeset viewer.