Jeśli jesteś właścicielem tej strony, możesz wyłączyć reklamę poniżej zmieniając pakiet na PRO lub VIP w panelu naszego hostingu już od 4zł!

Archive for the ‘Zend and PHP’ Category

How To Properly Inherit Methods From Prototype

How To Properly Inherit Methods From Prototype

JavaScript is using prototypal inheritance instead of the common class bases inheritance we are all used to from Java or C#. This can be difficult to understand at first. Consider the simple following example:

function Mammal(config) {
    this.config = config;
    console.log(this.config);
}

function Cat(config) {
    // call parent constructor
    Mammal.call(this, config);
}
// inherit all methods from Mammal's prototype
Cat.prototype = new Mammal();

var felix = new Cat({
    "name": "Felix"
});

We have a simple inheritance pattern here. Mammal is a parent class which accepts config as a constructor argument. Cat extends Mammal’s prototype. Everything looks ok but when you run this code in the browser you will see this in the console:

undefined fiddle.jshell.net/_display/:23
Object {name: "Felix"}

The problem is that we calling the Mammal’s constructor twice. First time, when we try to inherit all methods from the Mammal’s prototype in the Cat object. Second time, when creating instance of Cat.

The correct way of inheriting would be:

function Mammal(config) {
    this.config = config;
    console.log(this.config);
}

function Cat(config) {
    // call parent constructor
    Mammal.call(this, config);
}
// inherit all methods from Mammal's prototype
Cat.prototype = Object.create(Mammal.prototype);

var felix = new Cat({
    "name": "Felix"
});

Source: http://blog.richardknop.com/2013/06/how-to-properly-inherit-methods-from-prototype/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

How To Properly Inherit Methods From Prototype

How To Properly Inherit Methods From Prototype

JavaScript is using prototypal inheritance instead of the common class bases inheritance we are all used to from Java or C#. This can be difficult to understand at first. Consider the simple following example:

function Mammal(config) {
    this.config = config;
    console.log(this.config);
}

function Cat(config) {
    // call parent constructor
    Mammal.call(this, config);
}
// inherit all methods from Mammal's prototype
Cat.prototype = new Mammal();

var felix = new Cat({
    "name": "Felix"
});

We have a simple inheritance pattern here. Mammal is a parent class which accepts config as a constructor argument. Cat extends Mammal’s prototype. Everything looks ok but when you run this code in the browser you will see this in the console:

undefined fiddle.jshell.net/_display/:23
Object {name: "Felix"}

The problem is that we calling the Mammal’s constructor twice. First time, when we try to inherit all methods from the Mammal’s prototype in the Cat object. Second time, when creating instance of Cat.

The correct way of inheriting would be:

function Mammal(config) {
    this.config = config;
    console.log(this.config);
}

function Cat(config) {
    // call parent constructor
    Mammal.call(this, config);
}
// inherit all methods from Mammal's prototype
Cat.prototype = Object.create(Mammal.prototype);

var felix = new Cat({
    "name": "Felix"
});

Source: http://blog.richardknop.com/2013/06/how-to-properly-inherit-methods-from-prototype/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Build Pipeline Plugin’s Main Weakness

Build Pipeline Plugin’s Main Weakness

Build Pipeline Plugin is one of my favorite Jenkins plugins. It allows you to build a pipeline out of several jobs by defining upstream and downstream jobs. This way you can create a process consisting of multiple steps from running unit tests, various code quality tools (lint, mess detector, copy paste detector etc), BDD tests, through deployment to different environments (integration, functional test, production).

This allows you to manage whole journey of an application from committing to version control (Git, SVN etc) to deployment on production servers. In addition, the Build Pipeline Plugin also represents this journey in a very nice visual way.

The only big issue I have with this plugin relates to manually triggered parametrized jobs. The problem is, when you have a parametrized job which requires a manual submission (deployment to staging or production certainly does), it should ask you to manually enter the required parameters when you trigger the job from the pipeline view. This doesn’t happen and it triggers the build without any parameters.

This is quite annoying and has forced me to remove jobs like this from the pipeline for now (until the plugin is updated to support this very important feature…).

Source: http://blog.richardknop.com/2013/06/build-pipeline-plugins-main-weakness/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Build Pipeline Plugin’s Main Weakness

Build Pipeline Plugin’s Main Weakness

Build Pipeline Plugin is one of my favorite Jenkins plugins. It allows you to build a pipeline out of several jobs by defining upstream and downstream jobs. This way you can create a process consisting of multiple steps from running unit tests, various code quality tools (lint, mess detector, copy paste detector etc), BDD tests, through deployment to different environments (integration, functional test, production).

This allows you to manage whole journey of an application from committing to version control (Git, SVN etc) to deployment on production servers. In addition, the Build Pipeline Plugin also represents this journey in a very nice visual way.

The only big issue I have with this plugin relates to manually triggered parametrized jobs. The problem is, when you have a parametrized job which requires a manual submission (deployment to staging or production certainly does), it should ask you to manually enter the required parameters when you trigger the job from the pipeline view. This doesn’t happen and it triggers the build without any parameters.

This is quite annoying and has forced me to remove jobs like this from the pipeline for now (until the plugin is updated to support this very important feature…).

Source: http://blog.richardknop.com/2013/06/build-pipeline-plugins-main-weakness/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Quick Introduction To BDD Testing With Behat

Quick Introduction To BDD Testing With Behat

Behat is a PHP framework for BDD testing. It us very similar to Cucumber (RoR) or Behave (Django), it uses Gherkin language to define features and scenarions. These are then executed by Behat, which uses one or several drivers. In this short example I will show you how to use two drivers:

  • Goutte (simple HTTP based headless browser)
  • Selenium 2 (full browser emulator with JS support)

First, let’s use Composer to install Behat and the drivers:

{
    "name": "foo-bar",
    "description": "Foo Bar",
    "minimum-stability": "dev",
    "require": {
        "php": ">=5.3",
    },
    "require-dev": {
        "behat/behat": "dev-develop#1f1bead31e96da5e30fd5d499d5cf66d29b68cf6",
        "behat/mink": "v1.4.3",
        "behat/mink-extension": "dev-master#ef2c8639ebc254f0ff6e555b7834700caf5db9c4",
        "behat/mink-goutte-driver": "dev-master#v1.0.8",
        "behat/mink-selenium2-driver": "v1.0.6",
    }
}

Install the dependencies defined in composer.json file (above):

php composer.phar install --dev

Make sure you have Firefox 21 installed as that’s what we will be using for Selenium 2 tests. Also important, make sure you have Selenium 2 server installed and running. I have written a post explaining how to install Selenium 2 on Mac OS as a service.

This is an example behat.yml file I’m using in one of projects I work on:

default:
  paths:
    features: tests/functional/features
    bootstrap: tests/functional/features/bootstrap
  extensions:
    Behat\MinkExtension\Extension:
      base_url: http://virtualhost.local
      goutte: ~
      default_session: goutte
      javascript_session: selenium2
      selenium2:
        browser: firefox
        capabilities: { "browserName": "firefox", "browser": "firefox", "version": "21"}
        wd_host: http://127.0.0.1:4443/wd/hub

Then you can run the tests like this:

vendor/bin/behat --ansi

All tests with @javascript tag will use Selenium 2 driver (so a new Firefox window will pop up and your tests will run inside it), tests without @javascript tag will run using the headless Goutte driver.

You can exclude Selenium 2 tests like this (for example you might not have an external Selenium 2 server for Jenkins so you might want to run Selenium tests only locally and run only tests without @javascript tag on Jenkins as a part of the build process):

vendor/bin/behat --ansi --tags=~@javascript

Source: http://blog.richardknop.com/2013/06/quick-introduction-to-bdd-testing-with-behat/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Installing Selenium 2 On Mac OS As Service

Installing Selenium 2 On Mac OS As Service

Selenium 2 is a powerful browser emulator which enables you to automate frontend testing (especially JavaScript heavy pages). It can be used with Behat as well for BDD testing.

I prefer using Goutte headless driver to test basic functionality and flow of the application but sometimes there are critical parts of the app that rely heavily on client side technologies like JavaScript. Only way to test to those is to use a browser emulator (Selenium 2, Sahi etc). Enough talking, here is how I installed Selenium 2 server on Mac OS as a service:

wget https://selenium.googlecode.com/files/selenium-server-standalone-2.33.0.jar

sudo mkdir /usr/lib/selenium

sudo mv selenium-server-standalone-2.33.0.jar /usr/lib/selenium

sudo mkdir /var/log/selenium

sudo chmod -R a+w /var/log/selenium

Then you need to create a new file:

sudo nano ~/Library/LaunchAgents/org.nhabit.Selenium.plist

With contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>org.nhabit.Selenium</string>
        <key>OnDemand</key>
        <true/>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/bin/java</string>
                <string>-jar</string>
                <string>/usr/lib/selenium/selenium-server-standalone-2.33.0.jar</string>
                <string>-port</string>
                <string>4443</string>
        </array>
        <key>ServiceDescription</key>
        <string>Selenium Server</string>
        <key>StandardErrorPath</key>
        <string>/var/log/selenium/selenium-error.log</string>
        <key>StandardOutPath</key>
        <string>/var/log/selenium/selenium-output.log</string>
</dict>
</plist>

Load the service:

launchctl load ~/Library/LaunchAgents/org.nhabit.Selenium.plist
launchctl start org.nhabit.Selenium

You can also check it’s running:

ps aux | grep selenium

richardknop    19880   0.0  0.5  2859020  76648   ??  S     2:09pm   0:07.05 /usr/bin/java -jar /usr/lib/selenium/selenium-server-standalone-2.33.0.jar -port 4443
richardknop    20852   0.0  0.0  2432768    596 s001  R+    3:17pm   0:00.00 grep selenium

And error logs, just in case you need them:

tail -f /var/log/selenium/selenium-error.log

Source: http://blog.richardknop.com/2013/06/installing-selenium-2-on-mac-os-as-service/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Are Backbone Models Singletons?

Are Backbone Models Singletons?

I have been using Backbone (plus couple of other JavaScript libraries) for my last project. One of the first problems I encountered was this simple code:

var Foo = Backbone.Model.extend({
    defaults: {
        bars: []
    }
});

var foo = new Foo();
foo.get("bars").push("a");
foo.get("bars").push("b");
console.log(foo.get("bars"));

var foo = new Foo();
foo.get("bars").push("c");
foo.get("bars").push("d");
console.log(foo.get("bars"));

A simple model with array as a property, seems pretty straightforward. But when I created two instances of the model, this was logged in the console:

["a", "b", "c", "d"]
["a", "b", "c", "d"]

JSFiddle

Well, the problem was that the property declared in defaults is a global one. In order to avoid this rookie mistake, init all arrays or dictionaries in initialize method:

var Foo = Backbone.Model.extend({
    initialize: function() {
        this.set("bars", []);
    }
});

Here is my related StackOverflow question: Are Backbone Models Singletons?

Source: http://blog.richardknop.com/2013/06/are-backbone-models-singletons/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Faster Autoloading With Zend Framework 2

Faster Autoloading With Zend Framework 2

Standard autoloader that comes with Zend Framework 2 is not and ideal one to use in production environment. I would suggest using a classmap autoloader which is faster. Here is how it works. When installing dependencies specified in composer.json, use -o option in order to generate classmap file:

php composer.phar install -o

It will create a PHP file at vendor/composer/autoload_classmap.php path which contains a static array of all knows classes from dependencies (Zend Framework 2, Doctrine 2 etc) with namespaces and paths to files.

You should also autoload all your modules in the same way. Either do it manually – cd into module folder and generate the classmap file:

cd module/Foo
../../vendor/bin/classmap_generator.php -w

Or use ANT:

  1. <target name="classmapgenerator" description="">
  2.   <exec executable="php">
  3.    <arg value="${basedir}/vendor/zendframework/zendframework/bin/classmap_generator.php" />
  4.    <arg value="-w" />
  5.    <arg value="-l" />
  6.    <arg value="module/Foo" />
  7.   </exec>
  8.   <exec executable="php">
  9.    <arg value="${basedir}/vendor/zendframework/zendframework/bin/classmap_generator.php" />
  10.    <arg value="-w" />
  11.    <arg value="-l" />
  12.    <arg value="module/Bar" />
  13.   </exec>
  14.  </target>

Inside your Module.php, change getAutoloaderConfig() method to look like this:

  1. public function getAutoloaderConfig()
  2.     {
  3.         return array(
  4.             'Zend\Loader\ClassMapAutoloader' => array(
  5.                 __DIR__ . '/autoload_classmap.php',
  6.             ),
  7.         );
  8.     }

Finally, change your init_autoloader.php file:

  1. require_once __DIR__ . '/vendor/zendframework/zendframework/library/Zend/Loader/AutoloaderFactory.php';
  2. require_once __DIR__ . '/vendor/zendframework/zendframework/library/Zend/Loader/ClassMapAutoloader.php';
  3. Zend\Loader\AutoloaderFactory::factory(array(
  4.     'Zend\Loader\ClassMapAutoloader' => array(
  5.         'Composer' => __DIR__ . '/vendor/composer/autoload_classmap.php',
  6.     )
  7. ));

Done! I don’t have any benchmarks at the moment. If I will have more free time, I will run some benchmarks to see how much faster it is actually.

Source: http://blog.richardknop.com/2013/05/faster-autoloading-with-zend-framework-2/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Select a radio button with Mink / Behat

Select a radio button with Mink / Behat

Either I am completely blind or I just haven’t found an out-of-box solution for selecting a radio button with Mink / Behat. I have written a simple step definition which does this for me. In order for it to work, you have to have the radio button input element wrapped by a label element. Use the label text as argument:

/**
  1.  * @When /^I check the "([^"]*)" radio button$/
  2. */
  3. public function iCheckTheRadioButton($labelText)
  4.     {
  5.     foreach ($this->getMainContext()->getSession()->getPage()->findAll('css', 'label') as $label) {
  6.         if ($labelText === $label->getText() && $label->has('css', 'input[type="radio"]')) {
  7.             $this->getMainContext()->fillField($label->find('css', 'input[type="radio"]')->getAttribute('name'), $label->find('css', 'input[type="radio"]')->getAttribute('value'));
  8.             return;
  9.         }
  10.     }
  11.     throw new \Exception('Radio button not found');
  12. }
  13. <span class="st0"

Use it like this inside your feature:

When I check the "Enabled" radio button

Source: http://blog.richardknop.com/2013/04/select-a-radio-button-with-mink-behat/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>

Introduction to boto (Python interface to AWS)

Introduction to boto (Python interface to AWS)

More and more companies are using cloud storage for their files these days. There are many cloud services you can choose from (Windows Azure, Ubuntu Cloud, Amazon Web Services etc). I have used mainly Amazon Web Services (AWS) so I will show you how to easily upload files to S3 and how to copy files on S3 to different locations from Python script.

The only thing you need is Python and boto which is a Python interface to AWS. You can install it via pip:

pip install boto

Before uploading files to S3 you need to know your access key and secret key which will be provided to you by Amazon. You also need to create a bucket which is something like a namespace or a directory on S3. Once you have your access key, secret key and you have created a bucket, it’s easy to upload files to it with boto.

  1. from boto.s3.connection import S3Connection
  2.  
  3. YOUR_ACCESS_KEY_ID = "MY_ACCESS_KEY"
  4. YOUR_SECRET_ACCESS_KEY = "MY_SECRET_KEY"
  5. BUCKET = "MY_COOL_BUCKET"
  6.  
  7. conn = S3Connection(YOUR_ACCESS_KEY_ID, YOUR_SECRET_ACCESS_KEY)
  8. bucket = conn.get_bucket(BUCKET)
  9.  
  10. files_to_upload = {
  11.     '/path/to/hello.txt': 'hello_on_s3.txt'
  12.     '/path/to/world.txt': 'world_on_s3.txt'
  13. }
  14. for file_to_upload, s3_destination in files_to_upload.iteritems():
  15.     key = bucket.new_key(s3_destination)
  16.     key.set_contents_from_filename(file_to_upload)
  17.     key.set_acl('public-read')

Next thing you might want to do is to copy a file already uploaded to S3 bucket to a different location. This is how you do it:

  1. from boto.s3.connection import S3Connection
  2.  
  3. YOUR_ACCESS_KEY_ID = "MY_ACCESS_KEY"
  4. YOUR_SECRET_ACCESS_KEY = "MY_SECRET_KEY"
  5. BUCKET = "MY_COOL_BUCKET"
  6.  
  7. conn = S3Connection(YOUR_ACCESS_KEY_ID, YOUR_SECRET_ACCESS_KEY)
  8. bucket = conn.get_bucket(BUCKET)
  9.  
  10. files_to_copy = {
  11.     'hello_on_s3.txt' => 'foo_on_s3.txt',
  12.     'world_on_s3.txt' => 'bar_on_s3.txt'
  13. }
  14. for file_to_copy, new_destination in files_to_copy.iteritems():
  15.     bucket.copy_key(
  16.         new_destination,
  17.         BUCKET,
  18.         file_to_copy
  19.     )

The above code will copy the files to a different location in the same bucket. You can also specify a different bucket as well.

There are much more things you can do with boto. This post was just an introduction. Feel free to read the full boto documentation.

Source: http://blog.richardknop.com/2013/02/introduction-to-boto-python-interface-to-aws/

<!–
var d = new Date();
r = escape(d.getTime()*Math.random());
document.writeln('’);
//–>