Tuesday, April 5, 2016

Codeception - How to read YAML file entries


    It has been almost 2 years since my last post. Lately, I've been occupied with PHP unit, REST and acceptance tests.

   Codeception is a testing framework, built with PHP, that allows developers and QA professionals to create all sorts of tests for their projects. The syntax is almost human readable and clean. The framework itself is configurable and uses YAML syntax files to store parameters. This can be very handy at times, the question is, how to access those values.

   There are 1 core class that can help us with this \Codeception\Configuration and the process is very easy.

    Lets have a look at the following config file called api.suite.yml

class_name: ApiTester
modules:
    enabled:
        - \Helper\Api
        - REST:
                depends: PhpBrowser
                url:  'http://my.local.dev'
                part: Json
testdata:
    api_secret: '87897ddhgg'
    api_key: '7367hcfkdjhfkhfdkhf83787'

This file describes the configuration for the API test suite. Most RESTfull APIs use a key and/or  secret. To be able to use the values, the following lines of code will do the job:


$thisConfig = \Codeception\Configuration::config();
$apiSettings = \Codeception\Configuration::suiteSettings('api', $thisConfig);

$apiSecret = $apiSettings['testdata']['api_secret'];
$apiKey = $apiSettings['testdata']['api_key'];


Now we can use the variables in our tests.

Wednesday, August 27, 2014

How to extract function names/method names from a PHP class using bash

As a developer, every one of us needs to document the code. It's very handy to have all of the functions/method names from a class we made to explain what every one of does.
I suppose there are a lot of commercial solutions on the market, however, a developer should always accept new challenges, at least that's what I tend to do. Since we are dealing with PHP, and the most common environment for PHP is LAMP, I decide to use bash. After some research, I found that other people felt the necessity of a list of methods from a class, so after reading this post:
Extract function names and directories from php files

I managed to come up with a shell script that will use the same idea, but will be reusable. The code follows :

#!/bin/bash
IFS='/' read -ra ADDR <<< "$1"
#explode path and get the file name-last substring
tLen=`expr ${#ADDR[@]} - 1`
fName=${ADDR[$tLen]}
#make new filename
newFname="$fName.doc"
#print the current file
echo "*********Class $fName *********" >$newFname
#print the functions
find $1 -name '*.php' | xargs egrep -o 'p[a-zA-Z_]* function[ \t][ \t]*[a-zA-Z_]*([0-9a-zA-Z_]*)' >> $newFname

This will generate a new file with a heading and a list of all of the methods/functions in that file, i.e. if we want to list the NewUser.php file :


class NewUser{
   public function getName(){

   }
   public function getEmail(){

   }
   public function getAddress(){

   }
}


the output would be a new file NewUser.php.doc  :

*********Class NewUser.php *********
function getName
function getEmail
function getAddress


and there you go, you have a list of all of the methods in a PHP class.


 

Monday, February 4, 2013

Developing OpenCart Modules


 The OpenCart (http://www.opencart.com/) is an open-source shopping cart with a MySQL database back-end. Because I couldn't find any appropriate documentation when I was doing this, I decide I should share this, in case someone else gets stuck with a similar task/problem/challenge .

 More details about the OpenCart can be found here :


 It's an MVC concept, and the next image shows that (directory structure of the OpenCart):


In this post we will be talking about how to create a new module and the popular version of OpenCart in the time when I was working on this subject, was 1.5.1.3.

The OpenCart has two parts : the shopping cart front-end and the admin back-end . Both sections have almost identical directory and file structure.

Shopping Cart front-end:  The files for the shopping cart are (models, views, controller, language files) are located in the catalog directory.  The important files for this section are the  config.php file and the files located in the catalog directory.  The config.php file contains all of the settings (file paths, image paths, database username and password) and a user/developer can add additional settings.

Admin , back-end: The files for the admin section are located in the admin directory. The structure is same as  the front - end, the important file here is the config.php also (same as the front-end).

This means that, the module we are building, will have 2 parts, one used to interface with the front-end and another one used to interface with the back-end(admin).  Let's build a new payment module and call it ExpressPayment (the same method can be applied on your module).

The structure of the module will have:


  • front -end :
    • controller : located in catalog/controller/payment/express_payment.php
    • model : located in catalog/model/payment/express_payment.php
    • view: located in catalog/view/theme/[name_of_the_theme(default)]/template/payment/express_payment.tpl (more than one template can exist, depending on our goal and how are different messages handled)
    • language files: located in catalog/language/[language(english)]/payment/express_payment.php
  • admin section :
    • controller: located in admin/controller/payment/express_payment.php
    • view : located in  admin/view/template/payment/express_payment.tpl
    • language files :  located in  admin/language/[language(english)]/payment/express_payment.tpl


Front-end:

As I said, the OpenCart's structure is completely MVC oriented(personally, to me, it looks like someone took CodeIgniter and decided he could make a shopping cart). Let's go over the front-end components, one by one.

Controller : 
Every controller extends the main controller, named "Controller" (not very creative, but, pretty much, straight forward, isn't it?). It has a default/main method, called index() (If you ever had a chance to work with a popular framework, like Zend or CodeIgniter, this will look very familiar). You can add your own methods, depending on the functionality.

Model:

The typical model structure will contain methods for interacting with the database and/or the current session data. Every model extends the main model class, named "Model".

View:
I was never good at design, so I'm just going to describe the structure and functionality of a view. It's just a *.tpl file, containing the HTML and a couple of lines of PHP code.

Language files:
These files are PHP files, containing arrays with localized messages for your views.





Admin section:

As you can see, the structure is almost the same as the Front-end, only the model is missing here. This controller is accessed by the admin section, and it will be located under payment methods in the Extension menu.
You can add a check if the module was installed already (this will help if you want to define some custom fields in the database, you can run your queries here). The default method is index() . This method is called when the administrator clicks on the payment method, listed in the payment section. You will have to load any relevant data here, specific merchant token, long-term key...

I think it would be a waste of time for me to explain the structure of the template, because it's very simple and self-explaining (and I will paste in some example code at the end of my post).


You can use the files attached to try out the following .


Aaaaand, now....

Let's talk business. Let's assume that our payment method needs some sort of merchant ID, so the merchant using the cart can be identified, a token to confirm the merchant's identity . We (meaning I ) don't want to waste any time, so, we are going to make some changes by hand, in the database. Just a simple and fast insert() in the database will do the job for now. We need to add the 2 new fields, so we should do :

 insert into `setting` (`setting_id`, `store_id`, `group`, `key`, `value`, `serialized`)

values(24829, 0, 'express_payment', 'express_payment_token', 'token', 0),
values(24829, 0, 'express_payment', 'express_payment_merchant_id', 'merchant01', 0);

These are the default values of the fields. The insert() speaks for itself, so there's no point of explaining what's going on here.

Admin :
Here, the administrator/owner of the cart is setting up everything. Let's have a look at the payment method. If you go to Extensions => Payments, you should be see the payment method. If you click on it, the controller in admin/controller/payment/express_payment is called. First the language file is loaded, than the settings model is loaded and finally, the settings for this particular module (the two inserts).
That's it, nothing complicated.

Front-end:

Party time!!! Controller, loads data from database/session including , currency, amount, merchant ID, merchant token, loads a view. OpenCart has a modular template approach, this means that in most of the controllers, when a view i loaded, it doesn't load a whole page, but, the view itself is part of a bigger page. Why? Because OpenCart is AJAX based, javascript/jQuery makes a call to a specific controller, the controller returns HTML, but in a JSON format. If you look at the express payment controller, you'll see that  in the index() method, everything is read/loaded from somewhere, and then, the view is rendered. The view is actually returned as JSON, and represents an HTML form with a HTTP POST action. The callback is used to get response from your payment processor (transaction successful , failed, bad data , etc.).

Every order has history behind it, that's why we're using a call-back method, we have to keep a record.



All in all, I think I covered all of the things you need to create your own payment module. The same approach/concept can be used to make different type of module. Change the name and location, and you can create, well, what ever you like.

Example code, attached here: express_payment.zip.


Tuesday, September 25, 2012

How to make a nice menu.

This, and the previous post are jQuery related, because I played a lot with front-end stuff. Hopefully, I'll find some time and I'll publish some of the other things I did some time ago. So, let's not waste time. I'll not go into details, I believe the code is more or less self-explanatory.

 First, the HTML structure:



<span id="main_menu_bar">
  <span id="menu_item_wrapper">
<span id="men_item" class="active"><a href="#">Main Item1</a></span>
<span id="men_item"><a href="#">Main Item2</a></span>
  </span>
</span>
<div id="submenus">
</div>

The CSS:

menu_item_wrapper{
position: absolute;
height: 24px;
width: 1200px;
margin-bottom: 30px;
margin-top: 30px;
padding-left: 100px;
background-color: transparent;
}

#men_item{
position: relative;
padding: 0px;
margin-bottom: 30px;
margin-left: 10px;
margin-right: 10px;
margin-top: 10px;
background-color: transparent;
font-size: 122%;
}
#submenus{
position: fixed;
float: left;
display: none;
z-index: 101;

width: 70px;
height: 50px;

margin-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
padding-bottom: 10px;

border: none;
background-color: #F7BE81;
color: #000;

border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
-moz-border-radius-bottomleft:  5px;
-moz-border-radius-bottomright:  5px;
-webkit-border-bottom-left-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
}
#submenu_item a{
color: #000;
border: none;
margin-bottom: 10px;
}
#submenu_item:hover {
border-color: #000;
border-style: solid;
border-bottom: #000;
border-top:none;
border-left:none;
border-right:none;
border-width: 1px;
text-decoration: underline;
}

#submenu_item{
margin-bottom: 10px;
}

And, the jQuery code:

var submenu_visible = true;
$('#men_item.active').hover(function(){
  var p = $(this).position();
  $('#submenus').hide();
  $('#submenus').css('margin-left',p.left+10);
  $('#submenus').css('width',$(this).css('width'));
  $('#submenus').css('margin-top','55px');
  $('#submenus').html('<div id="submenu_item"><a href="http://localhost/">test</a></div><div id="submenu_item">
<a href="http://localhost/">test</a></div>');
                $('#submenus').show();
 });
        $('#submenus').mouseenter(function(){
                submenu_visible=true;
        });
        $('#submenus').mouseleave(function(){
                if(submenu_visible){
                    $(this).hide();
                    submenu_visible=false;
                }
        });
 $(document).click(function(){
  $('#submenus').hide();
  $('#submenus').html('');
 });
I hope I'l have time to share an example soon.

How to make a select editable using jQuery

I'm sure some of you had or have the need to make a html drop-down list editable. Well, if you didn't I did.

There are a lot of neat plug-ins out there, but, if you found yourself in a situation like me (compatibility issues), you'll definitely want/try to do it by yourself. Let me save you some time. I'll just copy/paste my code, works great under FF, Chrome, Opera, IE.

HTML:


Enter custom value in a select element
The trick is to hide the text field (using a CSS), and, when 'custom' is selected, show it. There's a onKeyUp event, when triggered, changes the value of the 'custom' child of the select.

<select id="select_element" name="select_element">
 <option value="1">1</option>
 <option selected="selected" value="2">2</option>
 <option value="3">3</option>
 <option value="4">4</option>
 <option id="custom_value" value="">custom</option>
</select>
<input id="custom" name="custom" type="text" />

jQuery code:

$(document).ready(function(){
//  enter a custom value 
$('#select_element').change(function(){
 if($(this).prop("selectedIndex") == 4){
 $('#custom').css('position','absolute');
 $('#custom').css('left',$(this).css('left'));
// add a pixel or two to the top, FF doesn't align the objects right 
 $('#custom').css('top',$(this).css('top')+2);
 $('#custom').css('width','40px');
// same as the top property
 $('#custom').css('height',$(this).css('height')-1);
 $('#custom').show();
 $('#custom').focus();
}
else{
 $('#custom').hide();
}
});
//  if the value changes, change the dropdown value also
$('#custom').keyup(function(){
 $('#custom_value').val($(this).val());
 console.log('The value you typed is:'+$('#custom_value').val());
});
});

and , finally , CSS:

body{
position: absolute;
width: 100%;
height: 100%;
margin:0px;
padding: 0px;
font-family: Arial, sans-serif;
}
#header_para{margin-left: 20%;}
.contentWrapper{margin-left:180px;}
#custom{
display:none;
z-index: 100;
position: relative;
float: left;
width: 43px;
margin: 0px;
}
#select_element{
z-index: 0;
position: absolute;
width: 60px;
}

and link to all of this:

edit_select.zip

I hope you'll find this usefull.

Intro...

Hi there. My name is Bojan Seirovski, Web developer according to my day job description. 

I am fooling around with some everyday stuff (if you are a web developer or in the same field), and I decided to share my findings with ... well with you, who ever you are.

OK, this is a place where I'll dump a lot of things that I already did. If you find any of these useful or not , please feel free to comment.