Programming Rambling

mrzard's ramblings in the wild

MySQL Query to Export Prestashop Data to a Shopify CSV

| Comments

If you find yourself migrating your shop from Prestashop to Shopify, you can use this query. It was written for an old version of Prestashop, but you probably won’t have much trouble adapting it to newer versions.

Also, take in consideration this query only outputs basic data, no variants, colors, etc. Also check which values do you need for ‘variant requires shipping’, ID_LANG, etc.

SELECT pl.link_rewrite as `Handle`, pl.name as `Title`, 
pl.description as `Body (HTML)`, 'VENDORNAME' as `Vendor`, pcl.`name` as `Type`, 
t.`name` as Tags, '' as `Option1 Name`, '' as `Option1 Value`, '' as `Option2 Name`, 
'' as `Option2 Value`, '' as `Option3 Name`, '' as `Option3 Value`, '' as `Variant SKU`, 
p.weight * 1000 as `Variant Grams`, '' as `Variant Inventory Tracker`, p.`quantity` 
as `Variant Inventory Qty`, 'deny' as `Variant Inventory Policy`, 'manual' 
as `Variant Fulfillment Service`, p.price as `Variant Price`, p.price_before 
as `Variant Compare At Price`, 'true' as `Variant Requires Shipping`, 'true' 
as `Variant Taxable`, '' as `Image Src` 
FROM 
    `ps_product` p 
    INNER JOIN `ps_product_lang` pl ON pl.`id_product` = p.`id_product` 
    LEFT JOIN `ps_product_tag` pt ON pt.`id_product` = p.`id_product` 
    LEFT JOIN `ps_tag` t ON t.`id_tag` = pt.`id_tag` 
    INNER JOIN `ps_image` pi ON pi.`id_product` = p.`id_product` 
    INNER JOIN `ps_category_lang` pcl ON pcl.`id_category` = p.`id_category_default` 
WHERE 
    pl.`id_lang` = ID_LANG 
    AND pcl.`id_lang` = ID_LANG 
    AND p.`id_category_default` IN (
        SELECT `id_category` 
        FROM `ps_category` WHERE `active` = 1
    ) 
    AND p.`active` = 1 GROUP BY p.`id_product`; 

Generate CSRF Token Programatically in Symfony 2

| Comments

If you find yourself in the need of generating a CSRF token for a ‘built’ Request or something in that fashion, you can do it rather easily:

Generate CSRF token programatically
1
2
3

$csrfProvider = $this->container->get('form.csrf_provider');
$csrfToken = $csrfProvider->generateCsrfToken('unknown');

‘unknown’ is the default ‘intention’ of CSRF tokens in Symfony2, change ‘unknown’ for the correct intention if you are using that option.

Release Cycles and Policies, Deploying Code Thoughts.

| Comments

In my programming experience I have worked with different ways of handling releases. From the old easy FTP access to other cool stuff like phing.

What I have learned is that it does not really matter which tools you use, and is pretty much contained in the next points.

0 - Prepare for the release. Write a ‘script’ of what code has been changed/added and what tests it must pass (unit, integration, user…). Iterate until all tests have passed. Then move the release to your staging server. Always have 100% awareness of what is going into the release.

1 - Have a proper staging server(s). This allows for good testing, and reduces (hopefully eliminates) the necessity to double check stuff in the live server(s).

3 - The release has to work. Test everything, then test it again. Then release. And go to 4.

4 - Shit happens. The relese does not always work. This is pretty common, specially with large codebases, multiple programmers and code merging (SVN I’m looking at you). Or discrepancies between your live servers and your testing servers. Or simply someone forgot to run a test.

5 - Your release system must work for you, not against you. It’s fine to have a release date / system, but fear not of changing it to fit your needs. This leads us to the next point.

6 - Make it that the release system is quick and can be fired anytime. You never know when you’re going to need an emergency fix. Make it easy to fix mistakes. Also make it painful to make them. You don’t want developers feeling confident they can release a half cooked solution and fix it later. I must confess though that I prefer to release and fix than to never release.

7 - Use of tools like phing can help you a lot automating some boring stuff, but again make deploying a simple procedure that has no bottlenecks and allows you to eliminate any serious enough bug or mistake in a heartbeat.

8 - Do not fire your lean, quick release system for everything. That CSS fix can wait until the next release.

Common Recruiting Errors Made by Companies.

| Comments

Lately I’ve seen a lot of posts about errors candidates make in interviews. Now I am going to write a list of error employers make when looking for candidates.

1 - Adding them in LinkedIn without asking or even introducing themselves.

Guys,we get it, you are important. Now, please, the thing is YOU came looking for us, not the other way around. Introduce yourself. Why are you adding me as a contact? Keep in mind we do not know each other. For me this is the professional equivalent to “hey, wanna hook up?” in a dating site.

2 - Recruting agencies special: Not disclosing which company they are recruiting for

Yes, I can understand you want to be discreet and everything, but again, you came looking for a candidate. Do you really expect a (hopefully) talented person to engage in a (possibly) lengthy selection process when they know nothing about their employer?

3 - Not stating salary / compensation

If you are out there looking for talent, that talent is most of the time already employed. Why waste your time and the candidate’s time by making him/her go to interviews just to know the salary bracket? Also, even for unemployed talent, they will be drawn to the offers that give the most information. Hiding this crucial piece of info makes no sense to me.

4 - Keeping a you're _sooooo_ lucky attitude

Yes, we are lucky because most of us love our jobs. That’s it. You came looking for us, not the other way around, this is a key concept. You are the lucky ones if we are the top-notch employees you are looking for: we make more money for you than from you.

5 - Not having tech people at the interview

Personal interviews are fine, but we usually want to discuss details. Which technologies are we going to use? How many users? How many people are on the team? Is there a lot of turnover? Do we have a VPN so we can work remotely? Frameworks? And these are just basic questions most of the time HR cannot answer. Please, please, please, have a tech person there.

Have I left something out? (Pretty sure I have). Don’t hesitate to comment and expand this list :D

Generate a Valid Google Premier Signature in PHP

| Comments

Google Premier requires for you to generate a signature over the URL you’re going to ask for, then send that signature alongside the request. Here is how to do it, as there is no PHP example in the Google Premier URL Signature documentation

In this code snippet we assume:

  • $request_url has the url that will be using the Google Premier service (for example, Static Maps API). It also already has the client param, sensor param, etc.
  • $signature_key has the key provided to you by Google
  • You are running this snippet from an authorized domain
  • Props to ZZ Coder at StackOverflow
Generate a valid Google Premier signature
1
2
3
4
5
6

$url_parts = parse_url($request_url); $signable_part = $url_parts['path'].'?'.$url_parts['query'];
$decoded_key = base64_decode(strtr($signature_key, '-_', '+/');
$url_signature = hash_hmac('sha1', $signable_part, $decoded_key), true);
$base64signature = strtr(base64_encode($url_signature), '+/', '-_');
$signature_param = '&signature='.urlencode($base64signature);

‘Strange’ things in this snippet:

  • Why the strtr()? Because Google uses URL-Safe base64
  • Why the true param at the end of hash_hmac? Because we need it the signature to be returned in binary before base64encondig it.

Then you just have to append $signature_param to your original request (which we’ve assumed is in $request_url) to have a correctly signed Google Premier request.

Ubuntu: Window Borders & Toolbars Gone.

| Comments

If you happen to run into this problem (you cannot resize your windows and have no access to window toolbars) in Ubuntu, the solution is pretty simple. Just run “gtk-window-decorator” (no quotes) from a terminal (or from ALT-F2) and you’re redy to go.

For Unity I read running “unity –reset” (again. no quotes) may help.

EDIT: If this happened in xfce, run “xfwm4 &” from a terminal.

Memcache vs Memcached (PHP): A Simple Explanation

| Comments

In a nutshell:

memcache is older, less mantained.

memcached is newer, developed by Digg people and generally preferred. Also it seems it is more configurable and has more options.

Complete explanation and opinions: http://serverfault.com/questions/63383/memcache-vs-memcached

Client comparision: http://code.google.com/p/memcached/wiki/PHPClientComparison

PECL pages:
http://pecl.php.net/package/memcache
http://pecl.php.net/package/memcached

Drag and Drop Interaction Made Easy With jQuery (and jQuery UI)

| Comments

Last week at work I had to make a drag-and-drop configurable homepage, where individual news items had to had the ability to be moved and arranged in a grid which represented the available placeholders on the homepage.

My work was made MUCH easier by the draggable and droppable plugins in jQuery UI. I just had to add a class which I binded the draggable plugin to to the news items and then add another class to the placeholders which I binded to the droppable plugin.

In case it’s of help for somebody, here’s a quick ‘skeleton’ on top of which you can code the drag&drop interactions you want.

Draggable-Droppable example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

  var draggable_options = {
          helper: 'clone',  /* makes the item 'move' a copy of itself rather than 
                         '   leave' the original area */
          revert: 'invalid',    /* makes the item return to its original position 
                             if not dropped in a 'droppable' area */
          cursor: 'move'       // changes the cursor appearance on hover 
  };

  //we give the items the draggable plugin with the options 
  $(".draggable").draggable(draggable_options);

  $(".droppable").droppable({
      drop: function(event, ui) {
          /* detect where we dropped the draggable element, 
         in my case, the key part was the element's id */
          var dropped_in = $(this).attr('id');
          
          /* here i put '...' in the droppable container's body to inform 
         the user 'something' is happening */
          var context = $(this);
          context.html('...');
          
          var dragged = $(ui.draggable);
          /* ui.draggable is a reference to the dropped element. 
         Now you can use all jQuery functions like dragged.attr('id') to get its id, 
         or dragged.html('whatever') to change its innerHTML, etc... */

          /* Here comes interaction, the removal of '...' and 
         display of the action results */
      }
  });