Plugin Directory

Changeset 2264429


Ignore:
Timestamp:
03/20/2020 10:41:00 AM (6 years ago)
Author:
thmarx
Message:

release 4.0.0

Location:
experience-manager/trunk
Files:
7 added
16 edited

Legend:

Unmodified
Added
Removed
  • experience-manager/trunk/assets/codemirror/codemirror.js

    r2192435 r2264429  
    174174  }
    175175
    176   var Delayed = function() {this.id = null;};
     176  var Delayed = function() {
     177    this.id = null;
     178    this.f = null;
     179    this.time = 0;
     180    this.handler = bind(this.onTimeout, this);
     181  };
     182  Delayed.prototype.onTimeout = function (self) {
     183    self.id = 0;
     184    if (self.time <= +new Date) {
     185      self.f();
     186    } else {
     187      setTimeout(self.handler, self.time - +new Date);
     188    }
     189  };
    177190  Delayed.prototype.set = function (ms, f) {
    178     clearTimeout(this.id);
    179     this.id = setTimeout(f, ms);
     191    this.f = f;
     192    var time = +new Date + ms;
     193    if (!this.id || time < this.time) {
     194      clearTimeout(this.id);
     195      this.id = setTimeout(this.handler, ms);
     196      this.time = time;
     197    }
    180198  };
    181199
     
    468486          order.push(new BidiSpan(0, start, i$7));
    469487        } else {
    470           var pos = i$7, at = order.length;
     488          var pos = i$7, at = order.length, isRTL = direction == "rtl" ? 1 : 0;
    471489          for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
    472490          for (var j$2 = pos; j$2 < i$7;) {
    473491            if (countsAsNum.test(types[j$2])) {
    474               if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
     492              if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); at += isRTL; }
    475493              var nstart = j$2;
    476494              for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
    477495              order.splice(at, 0, new BidiSpan(2, nstart, j$2));
     496              at += isRTL;
    478497              pos = j$2;
    479498            } else { ++j$2; }
     
    21922211  function updateLineWidgets(cm, lineView, dims) {
    21932212    if (lineView.alignable) { lineView.alignable = null; }
     2213    var isWidget = classTest("CodeMirror-linewidget");
    21942214    for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
    21952215      next = node.nextSibling;
    2196       if (node.className == "CodeMirror-linewidget")
    2197         { lineView.node.removeChild(node); }
     2216      if (isWidget.test(node.className)) { lineView.node.removeChild(node); }
    21982217    }
    21992218    insertLineWidgets(cm, lineView, dims);
     
    22252244    var wrap = ensureLineWrapped(lineView);
    22262245    for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
    2227       var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
     2246      var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget" + (widget.className ? " " + widget.className : ""));
    22282247      if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); }
    22292248      positionLineWidget(widget, node, lineView, dims);
     
    29482967    catch (e) { return null }
    29492968    var coords = coordsChar(cm, x, y), line;
    2950     if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
     2969    if (forRect && coords.xRel > 0 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
    29512970      var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
    29522971      coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
     
    35373556
    35383557  function setScrollTop(cm, val, forceScroll) {
    3539     val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
     3558    val = Math.max(0, Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val));
    35403559    if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
    35413560    cm.doc.scrollTop = val;
     
    35473566  // aligned.
    35483567  function setScrollLeft(cm, val, isScroller, forceScroll) {
    3549     val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
     3568    val = Math.max(0, Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth));
    35503569    if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
    35513570    cm.doc.scrollLeft = val;
     
    62686287      return {undo: done, redo: undone}
    62696288    },
    6270     clearHistory: function() {this.history = new History(this.history.maxGeneration);},
     6289    clearHistory: function() {
     6290      var this$1 = this;
     6291
     6292      this.history = new History(this.history.maxGeneration);
     6293      linkedDocs(this, function (doc) { return doc.history = this$1.history; }, true);
     6294    },
    62716295
    62726296    markClean: function() {
     
    65216545    if (files && files.length && window.FileReader && window.File) {
    65226546      var n = files.length, text = Array(n), read = 0;
    6523       var loadFile = function (file, i) {
    6524         if (cm.options.allowDropFileTypes &&
    6525             indexOf(cm.options.allowDropFileTypes, file.type) == -1)
    6526           { return }
    6527 
    6528         var reader = new FileReader;
    6529         reader.onload = operation(cm, function () {
    6530           var content = reader.result;
    6531           if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = ""; }
    6532           text[i] = content;
    6533           if (++read == n) {
     6547      var markAsReadAndPasteIfAllFilesAreRead = function () {
     6548        if (++read == n) {
     6549          operation(cm, function () {
    65346550            pos = clipPos(cm.doc, pos);
    65356551            var change = {from: pos, to: pos,
    6536                           text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
     6552                          text: cm.doc.splitLines(
     6553                              text.filter(function (t) { return t != null; }).join(cm.doc.lineSeparator())),
    65376554                          origin: "paste"};
    65386555            makeChange(cm.doc, change);
    6539             setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
     6556            setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change))));
     6557          })();
     6558        }
     6559      };
     6560      var readTextFromFile = function (file, i) {
     6561        if (cm.options.allowDropFileTypes &&
     6562            indexOf(cm.options.allowDropFileTypes, file.type) == -1) {
     6563          markAsReadAndPasteIfAllFilesAreRead();
     6564          return
     6565        }
     6566        var reader = new FileReader;
     6567        reader.onerror = function () { return markAsReadAndPasteIfAllFilesAreRead(); };
     6568        reader.onload = function () {
     6569          var content = reader.result;
     6570          if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) {
     6571            markAsReadAndPasteIfAllFilesAreRead();
     6572            return
    65406573          }
    6541         });
     6574          text[i] = content;
     6575          markAsReadAndPasteIfAllFilesAreRead();
     6576        };
    65426577        reader.readAsText(file);
    65436578      };
    6544       for (var i = 0; i < n; ++i) { loadFile(files[i], i); }
     6579      for (var i = 0; i < files.length; i++) { readTextFromFile(files[i], i); }
    65456580    } else { // Normal drop
    65466581      // Don't do a replace if the drop happened inside of the selected text.
     
    68526887  function endOfLine(visually, cm, lineObj, lineNo, dir) {
    68536888    if (visually) {
     6889      if (cm.doc.direction == "rtl") { dir = -dir; }
    68546890      var order = getOrder(lineObj, cm.doc.direction);
    68556891      if (order) {
     
    71067142    var order = getOrder(line, cm.doc.direction);
    71077143    if (!order || order[0].level == 0) {
    7108       var firstNonWS = Math.max(0, line.text.search(/\S/));
     7144      var firstNonWS = Math.max(start.ch, line.text.search(/\S/));
    71097145      var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
    71107146      return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
     
    72227258        { cm.replaceSelection("", null, "cut"); }
    72237259    }
     7260    if (gecko && !mac && !handled && code == 46 && e.shiftKey && !e.ctrlKey && document.execCommand)
     7261      { document.execCommand("cut"); }
    72247262
    72257263    // Turn mouse into crosshair when Alt is held on Mac.
     
    79277965    // handled in onMouseDown for these browsers.
    79287966    on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); });
     7967    on(d.input.getField(), "contextmenu", function (e) {
     7968      if (!d.scroller.contains(e.target)) { onContextMenu(cm, e); }
     7969    });
    79297970
    79307971    // Used to suppress mouse event handling when a touch happens
     
    86678708    var origDir = dir;
    86688709    var lineObj = getLine(doc, pos.line);
     8710    var lineDir = visually && doc.direction == "rtl" ? -dir : dir;
    86698711    function findNextLine() {
    8670       var l = pos.line + dir;
     8712      var l = pos.line + lineDir;
    86718713      if (l < doc.first || l >= doc.first + doc.size) { return false }
    86728714      pos = new Pos(l, pos.ch, pos.sticky);
     
    86828724      if (next == null) {
    86838725        if (!boundToLine && findNextLine())
    8684           { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir); }
     8726          { pos = endOfLine(visually, doc.cm, lineObj, pos.line, lineDir); }
    86858727        else
    86868728          { return false }
     
    97599801  addLegacyProps(CodeMirror);
    97609802
    9761   CodeMirror.version = "5.49.0";
     9803  CodeMirror.version = "5.52.0";
    97629804
    97639805  return CodeMirror;
  • experience-manager/trunk/experience-manager.php

    r2246815 r2264429  
    55  Description: The integration for the experience platform.
    66  Author: Thorsten Marx
    7   Version: 3.2.0
     7  Version: 4.0.0
    88  Author URI: https://wp-digitalexperience.com/
    99  Text Domain: tma-webtools
     
    1414}
    1515
    16 define("TMA_EXPERIENCE_MANAGER_VERSION", "3.2.0");
     16define("TMA_EXPERIENCE_MANAGER_VERSION", "4.0.0");
    1717define("TMA_EXPERIENCE_MANAGER_SEGMENT_MATCHING_ALL", "all");
    1818define("TMA_EXPERIENCE_MANAGER_SEGMENT_MATCHING_ANY", "any");
  • experience-manager/trunk/includes/backend/class.tma_settings.php

    r2237695 r2264429  
    5252        add_submenu_page('experience-manager/pages/tma-webtools-admin.php', __("Dashboard", "tma-webtools"), __("Dashboard", "tma-webtools"), 'manage_options', 'experience-manager/pages/tma-webtools-admin.php', null);
    5353        add_submenu_page('experience-manager/pages/tma-webtools-admin.php', __("Settings", "tma-webtools"), __("Settings", "tma-webtools"), 'manage_options', 'tma-webtools-setting-admin', array($this, 'plugin_page'));
     54       
     55        if (tma_exm_dependencies_fulfilled(["module-hosting"])) {
     56            add_submenu_page('experience-manager/pages/tma-webtools-admin.php', __("Hosting", "tma-webtools"), __("Hosting", "tma-webtools"), 'manage_options', 'experience-manager/pages/hosting.php', null);
     57        }
    5458    }
    5559
     
    5862            array(
    5963                'id' => 'tma_webtools_option',
    60                 'title' => __('Basic Settings', 'wedevs')
     64                'title' => __('Basic Settings', 'tma-webtools')
    6165            ),
    6266//          array(
  • experience-manager/trunk/includes/backend/segment/categories.php

    r2215120 r2264429  
    44    <p>
    55        Generate category pathes to use in the category rule <b>&quot;rule(CATEGORY).field("c_categories").path(...)&quot;</b>.
     6        Generate category pathes to use in the category rule <b>&quot;{ "conditional" : "category", "field" : "c_categories", "path" : "..." }&quot;</b>.
    67        Copy the value with leading und ending slash.
    78    </p>
  • experience-manager/trunk/includes/backend/segment/class.segment-editor-help.php

    r2215120 r2264429  
    8686            function updateSegment() {
    8787                if (window.exmSegmentEditor) {
    88                     let segmentData = "segment().site('" + exm_siteid + "')";
     88                    let segmentObject = {};
     89                    segmentObject.site = exm_siteid;
     90                    segmentObject.conditional = "and";
     91
     92                    segmentObject.conditions = [];
    8993                    let selectedVisit = document.querySelector("input[name='exm_visit']:checked").value;
    90                     let rules = [];
    9194                    if (selectedVisit === "first") {
    92                         rules.push("rule(FIRSTVISIT)")
     95                        segmentObject.conditions.push({"conditional": "firstvisit"})
    9396                    } else if (selectedVisit === "returning") {
    94                         rules.push("not(rule(FIRSTVISIT))")
     97                        segmentObject.conditions.push({"conditional": "not", "conditions": [{"conditional": "firstvisit"}]})
    9598                    }
    9699                    let devices = [];
    97100                    if (document.querySelector("[name='exm_device_mobile']").checked) {
    98                         devices.push("'Mobile Phone'");
     101                        devices.push("Mobile Phone");
    99102                    }
    100103                    if (document.querySelector("[name='exm_device_desktop']").checked) {
    101                         devices.push("'Desktop'");
     104                        devices.push("Desktop");
    102105                    }
    103106                    if (document.querySelector("[name='exm_device_tablet']").checked) {
    104                         devices.push("'Tablet'");
     107                        devices.push("Tablet");
    105108                    }
    106109                    if (devices.length > 0) {
    107                         rules.push("rule(KEYVALUE).name('device.type').values([" + devices.join(",") + "])");
     110                        segmentObject.conditions.push({"conditional": "keyvalue", "name": "device.type", "values": devices});
    108111                    }
    109                    
     112
    110113                    let selectedOrder = document.querySelector("input[name='exm_order']:checked").value;
    111114                    if (selectedOrder === "none") {
    112                         rules.push("rule(ECOMMERCE_ORDER).exact().count(0)")
     115                        segmentObject.conditions.push({"conditional": "ecommerce_order", "count": 0, "exact" : true});
    113116                    } else if (selectedOrder === "first") {
    114                         rules.push("rule(ECOMMERCE_ORDER).exact().count(1)")
     117                        segmentObject.conditions.push({"conditional": "ecommerce_order", "count": 1});
    115118                    } else if (selectedOrder === "active") {
    116                         rules.push("rule(ECOMMERCE_ORDER).count(3)")
     119                        segmentObject.conditions.push({"conditional": "ecommerce_order", "count": 3});
    117120                    }
    118121                    let selectedCoupon = document.querySelector("input[name='exm_coupon']:checked").value;
    119122                    if (selectedCoupon === "none") {
    120                         rules.push("rule(ECOMMERCE_COUPON).exact().count(0)")
     123                        segmentObject.conditions.push({"conditional": "ecommerce_coupon", "count": 0, "exact" : true});
    121124                    } else if (selectedCoupon === "lover") {
    122                         rules.push("rule(ECOMMERCE_COUPON).count(1)")
     125                        segmentObject.conditions.push({"conditional": "ecommerce_coupon", "count": 1});
    123126                    }
    124127
    125                     segmentData += ".and(" + rules.join(",") + ")";
    126                     window.exmSegmentEditor.setValue(segmentData);
     128                    window.exmSegmentEditor.setValue(JSON.stringify(segmentObject, null, "\t"));
    127129                }
    128130            }
  • experience-manager/trunk/includes/backend/segment/class.segment-editor-metabox.php

    r2215120 r2264429  
    5757                SegmentType::$TYPE   // Post type
    5858        );
     59       
     60        add_meta_box(
     61                'tma_segment_editor_support', // Unique ID
     62                'Support', // Box title
     63                [$this, 'support_banner'], // Content callback, must be of type callable
     64                SegmentType::$TYPE   // Post type
     65        );
    5966    }
    6067
     68    public function support_banner($post) {
     69        include 'banner.php';
     70    }
     71   
    6172    public function description($post) {
    6273        include 'description.php';
     
    104115                lineNumbers: true,
    105116                matchBrackets: true,
    106                 mode: "javascript"
     117                //mode: "javascript"
     118                mode : "application/json"
    107119            });
    108120        </script>
  • experience-manager/trunk/includes/backend/segment/class.segment-editor.php

    r2235008 r2264429  
    6262        }
    6363
    64         $value = get_post_meta($post->ID, 'tma_segment_synced', true);
    65 
     64        $segment = SegmentRequest::getInstance()->load_segment($post->ID);
     65       
     66        $value = FALSE;
     67        if ($segment && property_exists($segment, "attributes") && property_exists($segment->attributes, "modified") &&
     68                $post->post_modified === $segment->attributes->modified) {
     69            $value = true;
     70        }
    6671        if ($value) {
    6772            ?>
     
    135140
    136141        $siteid = tma_exm_get_site();
    137         $post_data = array(
     142        $segment = array(
    138143            'name' => $post->post_title,
    139144            'externalId' => $ID,
    140145            'site' => $siteid,
    141146            'active' => $post->post_status === "publish",
    142             'dsl' => $this->get_segment_dsl($post->ID),
    143             'period' => $this->get_segment_period($post->ID)
     147            'content' => $this->get_segment_dsl($post->ID),
     148            'period' => $this->get_segment_period($post->ID),
     149            'attributes' => [
     150                'modified' => $post->post_modified
     151            ]
    144152        );
    145153
    146154        tma_exm_log("post data");
    147         tma_exm_log(json_encode($post_data));
    148 
    149         $request = new \TMA\ExperienceManager\TMA_Request();
    150         $error = FALSE;
    151         try {
    152             $response = $request->post("/rest/audience", $post_data);
    153 
    154             if ($response !== FALSE) {
    155                 $code = wp_remote_retrieve_response_code($response);
    156                 $body_string = wp_remote_retrieve_body($response);
    157                 $body = json_decode($body_string);
    158                 tma_exm_log("code " . $code);
    159                 tma_exm_log("body " . $body_string);
    160 
    161                 if ($code === 200) {
    162                     if ($body->status === "ok") {
    163                         update_post_meta(
    164                                 $ID,
    165                                 'tma_segment_synced',
    166                                 true
    167                         );
    168                     } else {
    169                         $error = new \WP_Error("error", $response->body->message);
    170                     }
    171                 } else {
    172                     $error = new \WP_Error("error", "Error while accessing Experience Platform");
    173                 }
    174             } else {
    175                 $error = new \WP_Error("error", "Error while accessing Experience Platform");
    176             }
    177         } catch (Exception $ex) {
    178             $error = new \WP_Error("error", "error publishing audience: " . $ex->getMessage());
    179         } catch (\Unirest\Exception $uex) {
    180             $error = new \WP_Error("error", "error publishing audience: " . $uex->getMessage());
    181         }
    182         if ($error) {
    183             update_post_meta(
    184                     $ID,
    185                     'tma_segment_synced',
    186                     false
    187             );
     155        tma_exm_log(json_encode($segment));
     156
     157        $valid = SegmentValidator::getInstance()->validate($segment['content']);
     158        if ($valid !== TRUE) {
     159            $error = new \WP_Error("error", $valid);
     160        } else {
     161            $error = SegmentRequest::getInstance()->save_segment($ID, $post, $segment);
     162        }
     163        if ($error !== FALSE) {
    188164            $user_id = get_current_user_id();
    189165            set_transient("tma_segment_errors_{$post->ID}_{$user_id}", $error, 45);
     
    198174    public function delete($ID) {
    199175        tma_exm_log("delete");
    200 
    201         delete_post_meta(
    202                 $ID,
    203                 'tma_segment_synced'
    204         );
    205176
    206177        $site = tma_exm_get_site();
     
    220191        $request = new \TMA\ExperienceManager\TMA_Request();
    221192        $request->delete("/rest/audience?wpid=" . $ID . "&site=" . $site);
    222         update_post_meta(
    223                 $ID,
    224                 'tma_segment_synced',
    225                 false
    226         );
    227193    }
    228194
  • experience-manager/trunk/includes/backend/segment/description.php

    r2246815 r2264429  
    1616</style>
    1717<div class="tma_webtools">
    18     <?php
    19     $siteid = "";
    20     if (isset(get_option('tma_webtools_option')['webtools_siteid'])) {
    21         $siteid = get_option('tma_webtools_option')['webtools_siteid'];
    22     }
    23     ?>
    24     <h2>Your Site id: <b><?php echo $siteid; ?></b></h2>
     18   
    2519    <div>
    2620        <p>
    27             Your segment definition must start with: <b>segment().site(&quot;<?php echo $siteid; ?>&quot;)</b>
    28         </p>
    29         <p>
    30             Then a segment definition is simply a sequence of rules linked by AND, OR or NOT.
    31             <br/>
    32             <i>segment().site(&quot;<?php echo $siteid; ?>&quot;).<b>and</b>(&lt;rules&gt;)</i>
    33             <br/>
    34             <i>segment().site(&quot;<?php echo $siteid; ?>&quot;).<b>or</b>(&lt;rules&gt;)</i>
    35             <br/>
    36             <i>segment().site(&quot;<?php echo $siteid; ?>&quot;).<b>not</b>(&lt;rules&gt;)</i>
     21            The segment definition is basicly a list of conditionals, written in a simple JSON format.
    3722        </p>
    3823    </div>
    3924
    40     <h3>Rules</h3>
     25    <h3>Conditionals</h3>
    4126    <div>
    4227        <p>
     
    4530            All nested rules must match.
    4631            <br />
    47             <b>and(&lt;list of rules&gt;)</b>
     32            <b>{ "conditional" : "and", "conditions" : [...]}</b>
    4833        </p>
    4934        <p>
     
    5237            One of the nested rules must match.
    5338            <br />
    54             <b>or(&lt;list of rules&gt;)</b>
     39            <b>{ "conditional" : "or", "conditions" : [...]}</b>
    5540        </p>
    5641        <p>
     
    5944            None of the nested rules must match.
    6045            <br />
    61             <b>not(&lt;list of rules&gt;)</b>
     46            <b>{ "conditional" : "not", "conditions" : [...]}</b>
    6247        </p>
    6348        <p>
    64             <span class="headline">PAGEVIEW</span>
     49            <span class="headline">PageView</span>
    6550            <br />
    66             Test if a user has viewed a specific page or posttype. By confention use &lt;posttype&gt;#&lt;slug&gt;
     51            Test if a user has viewed a specific page or posttype.
    6752            <br />
    68             <b>rule(PAGEVIEW)</b>
     53            <b>{ "conditional" : "pageview" }</b>
    6954            <br />
    7055            <span class="subheadline">Examples</span><br/>
    71             <span>User has visited the homepage: </span><b>.rule(PAGEVIEW).page('the id').type('page').count(1)</b>
     56            <span>User has visited the homepage: </span><b>{ "conditional" : "pageview" , "page" : "page_id", "type" : "page", "count" : 1 }</b>
    7257            <br />
    73             <span>User has visited a product page: </span><b>.rule(PAGEVIEW).page('the id').type('product').count(1)</b>
     58            <span>User has visited a WooCommerce product page: </span><b>{ "conditional" : "pageview" , "page" : "product_id", "type" : "product", "count" : 1 }</b>
    7459        </p>
    7560        <p>
    76             <span class="headline">EVENT</span>
     61            <span class="headline">Event</span>
    7762            <br />
    7863            A specific event. See <a href="#events">Events Section</a> for all tracked events.
    7964            <br />
    80             <b>rule(EVENT)</b>
     65            <b>{ "conditional" : "event" }</b>
    8166            <br />
    8267            <span class="subheadline">Examples</span><br/>
    83             <span>User has visited at least two page: </span><b>rule(EVENT).event("pageview").count(2)</b>
     68            <span>User has visited at least two page: </span><b>{ "conditional" : "event", "event" : "pageview", "count" : 2 }</b>
    8469        </p>
    8570        <p>
    86             <span class="headline">FIRSTVISIT</span>
     71            <span class="headline">FirstVisit</span>
    8772            <br />
    8873            Check if it is the first visit of a customer.
    8974            <br />
    90             <b>rule(FIRSTVISIT)</b>
     75            <b>{ "conditional" : "firstvisit"}</b>
    9176        </p>
    9277        <p>
    93             <span class="headline">CATEGORY</span>
     78            <span class="headline">Category</span>
    9479            <br />
    9580            Check if a user has visited posts or products of a specific category.
    9681            User the category path generator to get the correct path: <a href="#exm_categories">Category path generator</a>
    9782            <br />
    98             <b>rule(CATEGORY).field('c_categories')</b>
     83            <b>{ "conditional" : "category", "field" : "c_categories"}</b>
    9984            <br />
    10085            <span class="subheadline">Examples</span><br/>
    101             <span>User has visited at least two post of a category: </span><b>rule(CATEGORY).path('/news/local').field('c_categories').count(2)</b>
     86            <span>User has visited at least two post of a category: </span><b>{ "conditional" : "category", "field" : "c_categories", "path" : "/news/local/", count: 2 }</b>
    10287            <br/>
    103             <span>User has visited at least two products of the category T-Shirts: </span><b>rule(CATEGORY).path('/tshirts/').field('c_categories').count(2)</b>
     88            <span>User has visited at least two products of the category T-Shirts: </span><b>{ "conditional" : "category", "field" : "c_categories", "path" : "/tshirts/", count: 2 }</b>
    10489        </p>
    10590        <p>
    106             <span class="headline">KEYVALUE</span>
     91            <span class="headline">KeyValue</span>
    10792            <br />
    10893            The KeyValue-Rule is a generic rule that is used for many purposes.         
    10994            <br />
    110             <b>rule(KEYVALUE).name('browser.name').values(['Chrome', 'Firefox'])</b>
     95            <b>{ "conditional" : "keyvalue"}</b>
    11196            <br />
    11297            "browser.name" (e.g. Chrome, Firefox, Edge, Safari) <br/>
    11398            "device.type" (e.g. Mobile Phone, Desktop, Tablet, Console, TV Device) <br/>
    11499            <span class="subheadline">Examples</span><br/>
    115             <span>User uses firefox or chrome browser: </span><b>rule(KEYVALUE).name('browser.name').values(['Chrome', 'Firefox'])</b>
     100            <span>User uses firefox or chrome browser: </span><b>{ "conditional" : "keyvalue", "name" : "browser.name", "values": ["Chrome", "Firefox"] }</b>
    116101            <br/>
    117             <span>User uses a desktop pc: </span><b>rule(KEYVALUE).name('device.type').values(['Desktop'])</b>
     102            <span>User uses a desktop pc: </span><b>{ "conditional" : "keyvalue", "name" : "device.type", "values": ["Desktop"] }</b>
    118103        </p>
    119104    </div>
  • experience-manager/trunk/includes/class.cookie.php

    r2201127 r2264429  
    5555                }
    5656            }
    57             setcookie($name, $value, time() + $expire, '/', $cookieDomain, true);
     57            setcookie($name, $value, time() + $expire, '/', $cookieDomain, false, false);
    5858        }
    5959
  • experience-manager/trunk/includes/class.plugins.php

    r2246815 r2264429  
    3030
    3131    public function woocommerce() {
    32         return in_array('woocommerce/woocommerce.php', $this->plugins);
     32        return in_array('woocommerce/woocommerce.php', $this->plugins)
     33                && is_plugin_active('woocommerce/woocommerce.php');
    3334    }
    3435    public function easydigitaldownloads() {
    35         return in_array('easy-digital-downloads/easy-digital-downloads.php', $this->plugins);
     36        return in_array('easy-digital-downloads/easy-digital-downloads.php', $this->plugins)
     37                && is_plugin_active('easy-digital-downloads/easy-digital-downloads.php') ;
    3638    }
    3739
     
    4547    public function popup_maker() {
    4648        return in_array('popup-maker/popup-maker.php', $this->plugins);
     49    }
     50   
     51    public function wp_popups() {
     52        return in_array('wp-popups-lite/wp-popups-lite.php', $this->plugins);
    4753    }
    4854
  • experience-manager/trunk/includes/class.request.php

    r2235008 r2264429  
    4949     * setup the request object and return
    5050     */
    51     public function get($url, $parameters = NULL, $headers = ['Content-Type' => "application/json"]) {
     51    public function get($url, $parameters = NULL, $headers = ['Content-Type' => 'text/plain', 'Accept' => 'application/json']) {
    5252
    5353        if (!isset($this->options["webtools_apikey"]) || !isset($this->options['webtools_url'])) {
     
    5757        tma_exm_log("get request: " . $url);
    5858
    59         $webtools_url = $this->clean_webtools_url($this->options['webtools_url']) . $this->clean_url($url);
     59        $webtools_url = $this->get_webtools_url() . $this->clean_url($url);
    6060//      $headers["apikey"] = $this->options["webtools_apikey"];
    6161
    62         $parameters = array();
    6362        $parameters['method'] = "GET";
    6463        $parameters['timeout'] = "45";
     
    6766//      $parameters['headers']['Content-Type'] = "text/plain";
    6867        $parameters['headers']['apikey'] = $this->options["webtools_apikey"];
     68        $parameters['headers']['site'] = tma_exm_get_site();
    6969
    7070        tma_exm_log(json_encode($parameters));
     
    8585        }
    8686
    87         $webtools_url = $this->clean_webtools_url($this->options['webtools_url']) . $this->clean_url($url);
     87        $webtools_url = $this->get_webtools_url() . $this->clean_url($url);
    8888
    8989        $parameters = array();
     
    9494        $parameters['headers']['Content-Type'] = "application/json";
    9595        $parameters['headers']['apikey'] = $this->options["webtools_apikey"];
     96        $parameters['headers']['site'] = tma_exm_get_site();
    9697
    9798        return $this->garded(function () use ($webtools_url, $parameters) {
     
    109110            return FALSE;
    110111        }
    111         $webtools_url = $this->clean_webtools_url($this->options['webtools_url']) . $this->clean_url($url);
     112        $webtools_url = $this->get_webtools_url() . $this->clean_url($url);
    112113
    113114        $parameters = array();
     
    119120        $parameters['headers']['Accept'] = "application/json";
    120121        $parameters['headers']['apikey'] = $this->options["webtools_apikey"];
     122        $parameters['headers']['site'] = tma_exm_get_site();
    121123
    122124        return $this->garded(function () use ($webtools_url, $parameters) {
     
    134136            return FALSE;
    135137        }
    136         $webtools_url = $this->clean_webtools_url($this->options['webtools_url']) . $this->clean_url($url);
     138        $webtools_url = $this->get_webtools_url() . $this->clean_url($url);
    137139
    138140        $parameters = array();
     
    144146        $parameters['headers']['Accept'] = "application/json";
    145147        $parameters['headers']['apikey'] = $this->options["webtools_apikey"];
     148        $parameters['headers']['site'] = tma_exm_get_site();
    146149
    147150        return $this->garded(function () use ($webtools_url, $parameters) {
     
    227230        return FALSE;
    228231    }
     232   
     233    private function get_webtools_url() {
     234        $url = $this->options['webtools_url'];
     235        if (!tma_endsWith($url, "/")) {
     236            return $url . "/";
     237        }
     238        return $url;
     239    }
    229240
    230241    public function track($event, $page, $customAttributes = null) {
     
    238249        $vid = \TMA\ExperienceManager\TMA_COOKIE_HELPER::getInstance()->getCookie(TMA_COOKIE_HELPER::$COOKIE_VISIT, UUID::v4(), TMA_COOKIE_HELPER::$COOKIE_VISIT_EXPIRE);
    239250        $apikey = $this->options["webtools_apikey"];
    240         $url = $this->options['webtools_url'];
     251        $url = $this->get_webtools_url();
    241252        $siteid = tma_exm_get_site();
    242253
     
    285296            $url = $this->options['webtools_url'] . 'rest/userinformation/user?apikey=' . $apikey . '&user=' . $userid
    286297                     . '&site=' . $site;
     298            tma_exm_log("url: " . $url);
    287299            $result = $this->loadContent($url, '{"user" : {"segments" : []}, "status" : "ok", "default": true}');
    288300
  • experience-manager/trunk/includes/modules/ads/advanced/class.advanced_ads.php

    r2201127 r2264429  
    5454        $settings_segments = $settings['segments'];
    5555
    56         $uid = \TMA\ExperienceManager\TMA_COOKIE_HELPER::getInstance()->getCookie(TMA_COOKIE_HELPER::$COOKIE_USER, UUID::v4(), TMA_COOKIE_HELPER::$COOKIE_USER_EXPIRE);
    57         $request = new TMA_Request();
    58         $response = $request->getSegments($uid);
    59 
    60         $user_segments = [];
    61         if ($response !== NULL) {
    62             $user_segments = tma_exm_get_user_segments();
    63         }
     56        $user_segments = tma_exm_get_user_segments();
    6457
    6558        //$user_segments = array_map('trim', $user_segments);
  • experience-manager/trunk/includes/modules/class.integrations.php

    r2246815 r2264429  
    5656            \TMA\ExperienceManager\TMA_PopupMakerIntegration::getInstance()->init();
    5757        }
     58        if (\TMA\ExperienceManager\Plugins::getInstance()->wp_popups() && $this->shouldInit("messaging_wp-popups")) {
     59            \TMA\ExperienceManager\WP_Popups::getInstance();
     60        }
     61       
    5862        if (\TMA\ExperienceManager\Plugins::getInstance()->advanced_ads() && $this->shouldInit("messaging_advancedads")) {
    5963            \TMA\ExperienceManager\TMA_AdvancedAdsIntegration::getInstance()->init();
     
    126130            ),
    127131            array(
     132                'name' => 'messaging_wp-popups',
     133                'label' => __("Enable WP Popups integration?", "tma-webtools"),
     134                'desc' => __("Enable targeting in the WP Popups", "tma-webtools"),
     135                'disable' => !\TMA\ExperienceManager\Plugins::getInstance()->wp_popups(),
     136                'type' => 'toggle',
     137                'default' => ''
     138            ),
     139            array(
    128140                'name' => 'messaging_advancedads',
    129141                'label' => __("Enable Advanced Ads integration?", "tma-webtools"),
  • experience-manager/trunk/includes/tma_functions.php

    r2246815 r2264429  
    1818    $user_segments = TMA\ExperienceManager\ShortCode_TMA_CONTENT::array_flat($user_segments);
    1919    tma_exm_log(json_encode($user_segments));
    20    
     20    $settings_segments = array_map('trim', $settings_segments);
     21    $user_segments = array_map('trim', $user_segments);
     22    $attr_segments = array_map('intval', $attr_segments);
     23    $user_segments = array_map('intval', $user_segments);
    2124    return TMA\ExperienceManager\ShortCode_TMA_CONTENT::matching_mode_all($user_segments, $settings_segments);
    2225}
     
    2629    tma_exm_log(json_encode($settings_segments));
    2730    $user_segments = TMA\ExperienceManager\ShortCode_TMA_CONTENT::array_flat($user_segments);
     31    $settings_segments = array_map('trim', $settings_segments);
     32    $user_segments = array_map('trim', $user_segments);
     33    $attr_segments = array_map('intval', $attr_segments);
     34    $user_segments = array_map('intval', $user_segments);
    2835    tma_exm_log(json_encode($user_segments));
    2936   
     
    3239
    3340function tma_exm_get_user_segments($defaultValue = []) {
     41    tma_exm_log("tma_exm_get_user_segments");
    3442    $request = new TMA\ExperienceManager\TMA_Request();
    3543    $response = $request->getSegments(\TMA\ExperienceManager\TMA_Request::getUserID());
    36     tma_exm_log(json_encode($response));
     44    tma_exm_log("tma_exm_get_user_segments: " . json_encode($response));
    3745    if ($response !== NULL && $response !== FALSE && $response->status === "ok" && property_exists($response->user, "actionSystem")) {
    3846//      $tma_config['user_segments'] = $response->user->actionSystem->segments;
     
    146154
    147155function tma_exm_is_elementor_active() {
    148     return \TMA\ExperienceManager\Plugins::getInstance()->elementor() && (\Elementor\Plugin::$instance->editor->is_edit_mode() || \Elementor\Plugin::$instance->preview->is_preview_mode());
     156    return \TMA\ExperienceManager\Plugins::getInstance()->elementor() && class_exists('\Elementor\Plugin') && (\Elementor\Plugin::$instance->editor->is_edit_mode() || \Elementor\Plugin::$instance->preview->is_preview_mode());
    149157}
    150158function tma_exm_beaver_is_preview() {
    151     return \TMA\ExperienceManager\Plugins::getInstance()->beaver() && \FLBuilderModel::is_builder_active();
     159    return \TMA\ExperienceManager\Plugins::getInstance()->beaver() && class_exists('\FLBuilderModel') && \FLBuilderModel::is_builder_active();
    152160}
    153161function tma_exm_is_editor_active() {
  • experience-manager/trunk/readme.txt

    r2246815 r2264429  
    44Requires at least: 4.4.1
    55Tested up to: 5.3.2
    6 Stable tag: 3.2.0
    7 Version: 3.2.0
     6Stable tag: 4.0.0
     7Version: 4.0.0
    88License: GPLv2 or later
    99
     
    2727* Support for Cache Plugins
    2828* Support for [Popup Maker](https://wppopupmaker.com/)
     29* Support for [WP Popups](https://wppopups.com/)
    2930* Support for [Advanced Ads](https://wpadvancedads.com/)
    3031
     
    6566
    6667== Changelog ==
     68
     694.0.0
     70 * New json based segment definition language introduced
     71 * Fix segmente sync state
     72 * Integration into WP Popups added
     73 * JS <-> PHP cookie issue fixed
     74 
     75Important: This version needs at least version 5.0.0 of the Experience Platform!
    6776
    68773.2.0
  • experience-manager/trunk/tma-autoload.php

    r2246815 r2264429  
    2525    // Popup Maker
    2626    "TMA\ExperienceManager\TMA_PopupMakerIntegration" => "includes/modules/messages/popup-maker/class.popup-maker.php",
     27    // WP Popups
     28    "TMA\ExperienceManager\WP_Popups" => "includes/modules/messages/wp-popups/class.wp-popups.php",
    2729    // Elementor
    2830    "TMA\ExperienceManager\Elementor_Integration" => "includes/modules/editors/elementor/class.elementor_integration.php",
     
    4547    "TMA\ExperienceManager\Segment\SegmentEditorHelp" => "includes/backend/segment/class.segment-editor-help.php",
    4648    "TMA\ExperienceManager\Segment\SegmentEditorMetaBoxes" => "includes/backend/segment/class.segment-editor-metabox.php",
     49    "TMA\ExperienceManager\Segment\SegmentRequest" => "includes/backend/segment/class.segment-request.php",
     50    "TMA\ExperienceManager\Segment\SegmentValidator" => "includes/backend/segment/class.segment-validator.php",
    4751    // Event Tracking
    4852    "TMA\ExperienceManager\Events\WC_TRACKER" => "includes/modules/events/class.woocommerce_tracker.php",
Note: See TracChangeset for help on using the changeset viewer.