techy stuff (23)


Docker – add host.docker.internal on linux

Just a quick note (for my own memory more than anything)…

If you need to connect from a docker container to something running on your local host, it can be a bit of a pain on Linux. On windows & Mac, there’s a special DNS entry ‘host.docker.internal’ which always points to the host machine. However that isn’t available on Linux (here’s a bug open for this as of May 2018: https://github.com/docker/for-linux/issues/264)

That bug report also contains a pretty good solution for this problem, so to save you wading through, simply add the following line to your docker file:

RUN ip -4 route list match 0/0 | awk '{print $3 "host.docker.internal"}' >> /etc/hosts

That adds an entry to the container’s Host file, so host.docker.internal will resolve to your host just like it does on Mac / Windows.




e-Commerce building blocks

I’ve been working in e-commerce for a good few years now, for very similar companies (early stage, fast fashion focussed) and there’s always the same sorts of problems to solve. Here’s a very basic, very generic guide to the things you need to get up and running. Each bit has a ‘too long / didn’t read’ summary at the end, so you can just look for those if you don’t like reading. Please note that this is entirely my opinion, I don’t get paid by any of the companies I mention (although I am totally open to bribery. Seriously guys, hit me up.)

I’m going to split this up into a few different sections:

  1. Your website
  2. Your logistics (warehouse etc)
  3. Your customer service
  4. Internal IT / infrastructure
  5. Data / Reporting

First up…..




Merchandise magento category by product age / availability

Just a quick snippet of code today, it grabs all the products in a certain category (given in category_id), sorts them by age and stock availability (you can adjust the relative weighting of these using $stock_weight) and then updates the category. The end result is a nice mix of newer products, and products with loads of stock towards the top of the category, older / lower stocked products further down.

This uses the external database script access script from: here

I should probably bundle this up into an extension, with a cron job and so on but…. I’ll leave that as an exercise for the reader!


$category_id = 8;
$stock_weight = 10;


$sql = "select ccp.*, DATEDIFF(Now(),cpe.created_at) as age,
(select sum(qty) from cataloginventory_stock_item as csi join catalog_product_super_link as cpsl on csi.product_id = cpsl.product_id where cpsl.parent_id = cpe.entity_id) as stock_qty,
((select DATEDIFF(Now(),MIN(created_at)) from catalog_product_entity) - (select age)) as age_factor,
(select stock_qty) * $stock_weight as stock_factor,
(select age_factor) + (select stock_factor) as sortby
from catalog_category_product as ccp
	join catalog_product_entity as cpe
		on cpe.entity_id = ccp.product_id
where ccp.category_id = $category_id
and cpe.type_id = 'configurable'
ORDER BY sortby DESC";


function build_query($results){
  $update_sql = "Insert into catalog_category_product (`category_id`,`product_id`,`position`) VALUES ";
  $pos = 0;
  foreach($results as $result){
    $pos++;
    $update_sql .= "('".$result['category_id']."','".$result['product_id']."','".$pos."'),";
  }
  $update_sql = rtrim($update_sql,',');
  return $update_sql;
}


require_once "include/db.php";

$db = new db();

$results = $db->query($sql);
$db->query("delete from catalog_category_product where category_id = $category_id");
$db->query(build_query($results));








Access magento database outside magento

Just a quick note, sometimes you need to access the magento database from a script, but don’t want the overhead of loading the whole magento framework….. Here’s a little snippet of code that  grabs the database details from the magento xml config, so you don’t have to store them in your script:

<?php
 class db {

 private $data = null;


 public function __construct(){
     $xml=simplexml_load_file(realpath(dirname(__FILE__))."/../../app/etc/local.xml");

     $host = (string) $xml->global->resources->default_setup->connection->host;
     $db = (string) $xml->global->resources->default_setup->connection->dbname;
     $user =(string) $xml->global->resources->default_setup->connection->username;
     $pass = (string) $xml->global->resources->default_setup->connection->password;
     $charset = 'utf8mb4';

     $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
     $opt = [
         PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
         PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
         PDO::ATTR_EMULATE_PREPARES => false,
     ];
     $this->data = new PDO($dsn, $user, $pass, $opt);
 }

 public function query($sql){
    return $this->data->query($sql)->fetchAll(PDO::FETCH_ASSOC);
 }

 }

 ?>

Save it somewhere like /magento_root/scripts/include/db.php and use it like this:
 

<?php

require "include/db.php"
$db = new db();

$results = $db->query('select * from cataloginventory_stock_item');

?>

 

 

 




Dev tooling with docker

This is the first in what will become a series of articles on development processes and techniques in use at my current place of work, Public Desire.  To start off with I’m going to take a run through our docker based development environment, then in future articles I might dip into our deployment processes and testing.  In my usual fashion I’m going to stay away from delving too deeply into the concepts and technical gubbins underlaying Docker and concentrate on the pragmatic business of getting a dev environment up and running.  If you’ve wanted to give docker a try, but found it a little intimidating give this a shot….




Chuwi Hi10 Pro keyboard / trackpad fix

Hi there, been a long time… nearly 6 months since I last posted anything.  Having a kid will do that to ya!

Anyway, this week I picked myself up a nifty little 2 in 1 tablet / laptop thingy from a chinese manufacturer I’d never heard of: The Chuwi Hi10 pro. For a grand total of £190 (£20 of which was import duty) I got this little beauty (after waiting a couple of weeks for delivery)

chuwi




Bannr.io

For the last couple of months I’ve been working on a platform to solve one of the problems I’ve seen repeated across numerous businesses in the ‘fast fashion’ ecommerce space.  The problem is how to update your homepage and site with the numerous promotions you’re running in a timely fashion without impacting site performance.  For the majority of businesses in this space, Magento is the platform of choice for the web facing side of the business.  Unfortunately Magento’s tools for this particular problem are lacking.  Smaller businesses tend to use CMS blocks with javascript timers to make sure their promotions show at the right time.  Moving up the scale, we have plugins for magento that allow cms blocks to be shown on a schedule.  And at the top end of the cost spectrum we have ‘personalization’ platforms that, as well as offering variant testing and personalization also offer the ability to schedule blocks of content.




Seeking new opportunities….

So, the time has come once again when I’m looking for new job opportunities.  As of the 1st of June I’ll be available for any fantastically interesting permanent opportunities in and around Manchester (Uk) or remote working.

you can view my linkedin profile here for a quick history of my experience, and if you want any further details contact me at [email protected] for a copy of my resume.




MVC Architecture

This will be a slight departure from my usual posts about random bits of code and have more a focus on architecture.

In the last few years the world of development has seen quite a bit of upheaval as it adapts to new ways of working, the devops movement has, when implemented well, proven incredibly effective in increasing ‘throughput’ of code as well as offering opportunities for team empowerment and increased stability of the final product.  Unfortunately, that ‘when implemented well’ is sometimes a sticking point.  The idea behind devops is too integrate development and operations, to make operations (ie: deployments, infrastructure) more code driven and automated.  What happens when it’s implemented badly though is that a separate ‘devops’ team is setup within an organisation, the majority of the members being sysadmins with maybe one guy who knows how to write bash scripts.  I’ll cover devops in more depth in another post, but what I want to focus on in this post is the move towards software defined architectures, and how that movement can be harnessed effectively.




Play spotify through a different sound device (windows)

Just a quick post today about how to solve a common (maybe) frustration…

My setup when I’m working is that I sit at my desk in the kitchen, with spotify open to have some nice background music going on. However, my nice amp with its decent bass levels and all the rest is sat in the living room. That’s not really a problem, since I have one of these which allows me to play music from my laptop via bluetooth to the amp. However, the standard setup in windows means that you have one ‘default’ sound device, and that’s the one that spotify uses. So if I want my system sounds to come out of my laptop speakers (rather than, for example, conducting skype conversations via my amp) it means I have to play music through the laptop speakers as well.

Until I found this:

http://www.equalify.me/

With the simple addition of this rather wonderful piece of (free update: equalify is no longer free according to comments from readers, it now costs $5) software I can happily play spotify through my amp via bluetooth while keeping everything else through my ‘default’ laptop speakers.

Here’s how it works. First, in windows select your default audio device. Remember, this should be the device you want everything except spotify to play through.

The easiest way to do this is to right click on the volume mixer icon in your taskbar and select ‘playback devices’. You should see a window like this:

Untitled

right click on the device you want to use as the default (if it isn’t already set as such) and select ‘set as default’. Again, remember this is the device you want to play everything except spotify through.

Now, download and install equalify from here: http://www.equalify.me/?page=download

Once it’s installed, fire up spotify and you should see a new icon next to your search bar, like this: 1

Click it, and the equalify window should open at the top left of your spotify window. Right click on the equalify window and wight click to activate the context menu. Select ‘options’ and then ‘change sound device’ like so:

Untitled

From the window that pops up, use the drop down to select the audio device you want to use and then click ‘Set New Output Device’:

Untitled

Now restart spotify.

And that’s pretty much it, spotify should now play through the device you selected.

As well as allowing playback through different audio devices, equalify also acts as an equaliser… if you like that sort of thing.