Category: "Ajax/JSON"

ibexa - stimulus - webpack

It's 4:20a - please excuse this post ...

I wanted to use the ibexa REST API to dump the content types

So - I needed to add some JavaScript. Stimulus was there, so I figured I'd use it. It's cool.

I haven't worked with this stuff ... ever

I had to upgrade webpack or encore or something

Which identified path issues in the ibexa CSS and SCSS

I was hoping it would be quicker to fix the issues than ... not fix them, so I tried and am posting the results here so that eventually I can fork the repo and make a proper pull request

If you're looking for a rough example of working with Stimulus, Symfony and the Ibexa REST API - https://github.com/bgamrat/improved-journey/commit/c2ee360c8167395e4a1d5af7992ea1e0bf921124

If you found this helpful - yay :)

vendor/ezsystems/ezplatform-admin-ui-assets/Resources/public/vendors/alloyeditor/dist/alloy-editor/assets/alloy-editor-atlas.css
3,7c3,7
< src:url('./fonts/alloyeditor-atlas.eot');
< src:url('./fonts/alloyeditor-atlas.eot?#iefix') format('embedded-opentype'),
< url('./fonts/alloyeditor-atlas.woff') format('woff'),
< url('./fonts/alloyeditor-atlas.ttf') format('truetype'),
< url('./fonts/alloyeditor-atlas.svg#alloyeditor-atlas') format('svg');
---
> src:url('fonts/alloyeditor-atlas.eot');
> src:url('fonts/alloyeditor-atlas.eot?#iefix') format('embedded-opentype'),
> url('fonts/alloyeditor-atlas.woff') format('woff'),
> url('fonts/alloyeditor-atlas.ttf') format('truetype'),
> url('fonts/alloyeditor-atlas.svg#alloyeditor-atlas') format('svg');

vendor/ezsystems/ezplatform-richtext/src/bundle/Resources/public/scss/_alloyeditor-ez.scss
3,7c3,7
< src: url('../fonts/alloyeditor-ez.eot');
< src: url('../fonts/alloyeditor-ez.eot?#iefix') format('embedded-opentype'),
< url('../fonts/alloyeditor-ez.woff') format('woff'),
< url('../fonts/alloyeditor-ez.ttf') format('truetype'),
< url('../fonts/alloyeditor-ez.svg#alloyeditor-ez') format('svg');
---
> src: url('/bundles/ezplatformrichtext/fonts/alloyeditor-ez.eot');
> src: url('/bundles/ezplatformrichtext/fonts/alloyeditor-ez.eot?#iefix') format('embedded-opentype'),
> url('/bundles/ezplatformrichtext/fonts/alloyeditor-ez.woff') format('woff'),
> url('/bundles/ezplatformrichtext/fonts/alloyeditor-ez.ttf') format('truetype'),
> url('/bundles/ezplatformrichtext/fonts/alloyeditor-ez.svg#alloyeditor-ez') format('svg');

vendor/ezsystems/ezplatform-admin-ui/src/bundle/Resources/public/scss/_preview.scss
115c115
< background: url('../img/preview-tablet.png') top center no-repeat;
---
> background: url('/bundles/ezplatformadminui/img/preview-tablet.png') top center no-repeat;
127c127
< background: url('../img/preview-mobile.png') top center no-repeat;
---
> background: url('/bundles/ezplatformadminui/img/preview-mobile.png') top center no-repeat;

vendor/ezsystems/ezplatform-admin-ui/src/bundle/Resources/public/scss/_login.scss
18c18
< background-image: url('../img/login-background.jpg');
---
> background-image: url('/bundles/ezplatformadminui/img/login-background.jpg');

vendor/ezsystems/ezplatform-admin-ui/src/bundle/Resources/public/scss/_error-page.scss
64c64
< background-image: url('../img/errors/background.png');
---
> background-image: url('/bundles/ezplatformadminui/img/errors/background.png');

Also - I had to reset my password for this blog for the umpteenth time ...

Quick Apache Benchmark test with log in

I have been looking at performance for a web application. I am using ab to compare the response times while adjusting the database indexing.

# 'log in'
curl -L https://www.example.com/login.php -k -b cookie -c cookie-jar -d username=admin -d password=**** -s > /dev/null
# Run the test -n times (in this case 10)
ab -C `grep PHP_session cookie-jar | cut -f6,7 | tr '\t' '='` -n 10 'https://www.example.com/main.php'

What's happening?

The curl command is logging in to the application and saving the cookies in a file named cookie-jar.

The grep command is extracting the session id cookie - name and value - from the cookie-jar and using it to authorize access to a main page for ab.

This post courtesy of Game Creek Video

iPhone "Incorrect Password" WiFi

If your iPhone is not connecting to your NetGear WNDR4000 WiFi router and the message is "Incorrect password", check the access control settings on the router.

iPhone &quot;Incorrect Password&quot; WiFi

I made a change to the router configuration and managed to enable access control which allowed only one device to log in.

Oops

DataTables - Passing Data to the Server in Client-Side processing mode

DataTables is AWESOME. I use it for list-based selection, table-based editing, data display and filtering and anything else I can think of because it is so robust that virtually anything is possible. Really.

If the dataset being used is fairly small (you may interpret small any way you like), DataTables client-side processing is amazing. It sorts and filters, updates all the navigation, lets you adjust the number of records displayed - as well as many more optional features - with very little effort.

Client-side processing - where filtering, paging and sorting calculations are all performed in the web-browser.


Ref: https://datatables.net/manual/data/#Client-side-processing

but

For client-side processing no additional data is submitted to the server

Ref: https://datatables.net/reference/option/ajax.data

The goal was to have a single client-side datatable which would display different content based on the user's actions. For example, 'list all the items with a status of "new" and a (time) segment of 1'.

HTML for the DataTable

<table id="datatable" class="display" cellspacing="0" width="100%">
  <thead>
    <tr>
      <th>Id</th>
      <th>Vendor</th>
      <th>Item</th>
      <th>Date</th>
    </tr>
  </thead>
</table>

JavaScript


var datatable;
$(function($){
    datatable = $('#datatable').DataTable(
         {
           "ajax": {
                        "url":  "data-10-1.php"
           },
           "columns":
           [
               {"data": "link"},
               {"data": "vendor"},
               {"data": "item"},
               {"data": "date"}
          ]
  });
  // Handle the click events
  $(".summary").on("click", function(evt){
        var target = evt.target, status, segment;
        if (target.hasAttribute("data-status")) {
            status=$(target).attr("data-status");
            segment=$(target).attr("data-segment");
            datatable.ajax.url("data-"+status+"-"+segment+".php");
            datatable.ajax.reload();
            datatable.draw('full-reset');
        }
    });
});

Notice that the URLs are variable. The status and segment values are passed in the URL itself, there is no POST or GET data.

Sample HTML which invokes the event handler. This HTML is inside the div with class="summary".

 <span class="details" data-status="10" data-segment="4" data-status-text="new">84</span>

In order to extract the status and segment out of the URL, you can use Apache RewriteRules, like so:


<directory /var/www/html>
    RewriteEngine On
    RewriteRule  ^(data)-(\d+)-(\d+)(\.php)$ $1$4?status=$2&segment=$3 [L]
</directory>

status and segment can then be accessed as $_GET variables. Be sure to validate them.

How does it work? As the user clicks on the spans, the event handler reads the data attributes and constructs a URL that is sent to the server. When Apache receives the request, it rewrites it to deliver the data embedded in the URL as GET parameters.

This post courtesy of Game Creek Video

Web application session timeout code

Session timeout warning for a web application with a variety of page layouts and frequent use of multiple tabs.

Nutshell explanation - ping the server, if you get a 403, show a huge red bar across the top of whatever page pinged.

Result:

  • It is immediately apparent the tab has timed out
  • If one tab times out, it does not disrupt the others
  • There is a link to help the user log in again

function sessionPing() {
    var pinger;
    function doPing() {
        var pReq = new XMLHttpRequest();
        pReq.addEventListener("load", function () {
            var sessionExpired, sessionExpiredMessage;
            var reloadLink;
            if (this.status === 403) {
                clearInterval(pinger);
                sessionExpired = document.createElement("div");
                // Sometimes an inline style is really the best solution
                sessionExpired.setAttribute("style","display:block; width: 100%; line-height: 2.5em; position:absolute; top:0; z-index:10000; text-align: center; background-color: #f00; color: #fff; font-family: 'Trebuchet MS',sans; font-size: 1.5em; font-style: italic");
                sessionExpiredMessage = document.createTextNode("Session expired ");
                sessionExpired.appendChild(sessionExpiredMessage);
                reloadLink = document.createElement("a");
                reloadLink.href = location.href;
                reloadLink.textContent = "Click to Continue";
                reloadLink.setAttribute("style","font-size:0.7em;color:#ddd");
                sessionExpired.appendChild(reloadLink);
                document.body.insertBefore(sessionExpired, document.body.firstChild);
                document.title = "Session expired";
            }
        });
        pReq.open("GET", "/ping.php");
        pReq.send();
    }
    pinger = setInterval(doPing, 30000);
}
sessionPing();


<?php
session_start();
if (empty($_SESSION['user_id'])) {
    header('HTTP/1.1 403 Forbidden');
    exit;
}
header('HTTP/1.1 201 No content');
exit;

One may argue that the page should be cleared, in this case, I chose to leave it up so people can copy the content off.

Confession: I didn't test this code, it is an extract.

This post courtesy of Game Creek Video

1 3 4 5 ...6 7