Wednesday, October 22, 2014

[Semantical Error] in Apigility and Symfony2 with MongoDB

If you encountered similar error below when you send a request to your Apigility REST service:
type: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,
title: "Internal Server Error",
status: 500,
detail: "[Semantical Error] The annotation \"@Doctrine\\ODM\\MongoDB\\Mapping\\Annotations\\ReferenceOne\" in property Shop\\StoreBundle\\Document\\Product::$shop does not exist, or could not be auto-loaded."
You made some changes in your MongoDB Document and somehow corrupted the app/cache/dev of your Symfony2 installation.

Quick Fix

Delete the app/cache/dev directory in your Symfony2 installation then visit your Symfony2 application page in your browser e.g. http://acmestore.local/app_dev.php/hello/user, Symfony2 will create new app/cache/dev directory then try sending your request to your Apigility REST service.

Tuesday, October 21, 2014

Implementing Apigility and Symfony2 with MongoDB

I wrote this as a personal note but posting it now publicly hoping it will also benefit others who are looking to implement Apigility with Symfony2 and MongoDB. This implementation is based on Enrico Zimuel's http://www.zimuel.it/create-api-symfony2-apigility/.

Create a directory where you will place both symfony and apigility installations e.g.
1
2
/var/www/acmestore.local/public_html/apigility
/var/www/acmestore.local/public_html/symfony

Install Symfony

1
composer create-project symfony/framework-standard-edition /var/www/acmestore.local/public_html/symfony/ "2.3.*"

According to symfony manual, before running Symfony for the first time, execute the following command to make sure that your system meets all the technical requirements:

1
$ php app/check.php

Also make sure that both:

1
2
app/cache
app/logs
are writable.

Install Symfony DoctrineMongoDBBundle

Add the following to your symfony's composer.json


1
2
3
4
5
6
7
/var/www/acmestore.local/public_html/symfony/composer.json
{
    "require": {
        "doctrine/mongodb-odm": "1.0.*@dev",
        "doctrine/mongodb-odm-bundle": "3.0.*@dev"
    },
}

and install the dependencies by running Composer's update command from the directory where your composer.json file is located:


1
composer update doctrine/mongodb-odm doctrine/mongodb-odm-bundle

Register the annotations library by adding the following to the autoloader (below the existing AnnotationRegistry::registerLoader line):


1
2
3
// app/autoload.php
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
AnnotationDriver::registerAnnotationClasses();

Update your AppKernel.php file, and register the new bundle:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Doctrine\Bundle\MongoDBBundle\DoctrineMongoDBBundle(),
    );

    // ...
}

And setup the basic configuration


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# app/config/config.yml
doctrine_mongodb:
    connections:
        default:
            server: mongodb://localhost:27017
            options: {}
    default_database: test_database
    document_managers:
        default:
            auto_mapping: true

Sample Bundle: Store Bundle


1
php app/console generate:bundle --namespace=Acme/StoreBundle


Create the Document Class


1
2
3
4
5
6
7
8
9
// src/Acme/StoreBundle/Document/Product.php
namespace Acme\StoreBundle\Document;

class Product
{
    protected $name;

    protected $price;
}

Add Mapping Information


 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
// src/Acme/StoreBundle/Document/Product.php
namespace Acme\StoreBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\Document
 */
class Product
{
    /**
     * @MongoDB\Id
     */
    protected $id;

    /**
     * @MongoDB\String
     */
    protected $name;

    /**
     * @MongoDB\Float
     */
    protected $price;
}

Generate corresponding Getters and Setters

1
php app/console doctrine:mongodb:generate:documents AcmeStoreBundle

Install Apigility

1
composer create-project -sdev zfcampus/zf-apigility-skeleton /var/www/acmestore.local/public_html/apigility/

Put it in development mode
1
2
cd path/to/install
php public/index.php development enable # put the skeleton in development mode

Make sure module/ and config/ are writable.

Important:
Add all the dependencies used by composer.json of your Symfony2 application

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
"symfony/symfony": "2.3.*",
"doctrine/orm": "~2.2,>=2.2.3",
"doctrine/doctrine-bundle": "1.2.*",
"twig/extensions": "1.0.*",
"symfony/assetic-bundle": "2.3.*",
"symfony/swiftmailer-bundle": "2.3.*",
"symfony/monolog-bundle": "2.3.*",
"sensio/distribution-bundle": "2.3.*",
"sensio/framework-extra-bundle": "2.3.*",
"sensio/generator-bundle": "2.3.*",
"incenteev/composer-parameter-handler": "~2.0",
"doctrine/mongodb-odm": "1.0.*@dev",
"doctrine/mongodb-odm-bundle": "3.0.*@dev"
and add the following

1
2
"autoload": {
        "psr-0": { "": "/var/www/acmestore.local/public_html/symfony/src/" }

to the composer.json of your Apigility installation and run composer update command.

Create your API (e.g. Store) and REST service (e.g. Product) and define the fields that correspond to the Product Document's fields you created earlier i.e. name and price.

In your Product REST service, under Settings -> REST Parameters, update the Hydrator Service Name field to "Zend\Stdlib\Hydrator\ClassMethods"

In Settings -> Service Class Names, update the Entity Class field to your Symfony's MongoDB Document class "Acme\StoreBundle\Document\Product"

Use your Symfony 2 MongoDB Document in your Apigility Resource

The idea is to bootstrap your Symfony 2 application in your Apigility's ProductResource class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# /var/www/acmestore.local/public_html/apigility/module/Store/src/Store/V1/Rest/Product/ProductResource.php

namespace Status\V1\Rest\Status;

use ZF\ApiProblem\ApiProblem;
use ZF\Rest\AbstractResourceListener;
use Acme\StoreBundle\Document\Product;

class ProductResource extends AbstractResourceListener
{
    protected $dm;
    
    public function __construct()
    {
        $symfonyApp = '/var/www/acmestore.local/public_html/symfony';
        require_once $symfonyApp . '/app/AppKernel.php';
        
        $kernel = new \AppKernel('dev', true);
        $kernel->loadClassCache();
        $kernel->boot();
        
        $this->dm = $kernel->getContainer()->get('doctrine_mongodb')->getManager();
    }

And use the document manager in other methods of the ProductResource.php
e.g.

 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
33
34
   /**
     * Create a resource
     *
     * @param  mixed $data
     * @return ApiProblem|mixed
     */
    public function create($data)
    {
        //return new ApiProblem(405, 'The POST method has not been defined');
        
        $product = new Product();
        $product->setName($data->name);
        $product->setPrice($data->price);
        
        $this->dm->persist($product);
        $this->dm->flush();
        
        return $product;
    }

    /**
     * Fetch a resource
     *
     * @param  mixed $id
     * @return ApiProblem|mixed
     */
    public function fetch($id)
    {
        //return new ApiProblem(405, 'The GET method has not been defined for individual resources');
        
        $product = $this->dm->getRepository('AcmeStoreBundle:Product')->find($id);
        
        return $product;
    }

Friday, November 19, 2010

Samsung Galaxy S Step by Step Lag Fix Procedure

This is the step by step procedure in applying one click lag fix in your Samsung Galaxy S GT-i9000 device.

Search and install "oclf" from Android Market then launch the "One Click Lag Fix" application

Root your device
Tap "Root Device Recovery 2e" and Fire It Up (after rooting, it will ask you to reboot. at this stage, you need to turn off your device and enter to recovery mode)

Recovery Mode
To enter to recovery mode, while the device is off, press and hold "Volume Up" + "Home" + "Power" buttons until the Samsung splash/intro screen shows up, use the Volume Up and Down buttons to select "apply sdcard:update.zip" and press "Home" button. The device will automatically reboot.

Convert from RFS to EXT2
Tap "Install EXT2 Tools" and Fire It Up then go back to main application screen, if "Undo OneClickLagFix V2+" is still unavailable, exit the application then re-launch it.
Now tap "OneClickLagFix V2+" and leave the default EXT Size (mine is 856 MB) then Fire It Up, it will reboot once finished processing.

Extra Tweak
Tap "Alter minfree", select Strict and check "Set On Boot"
Tap "Change Scheduler", select "deadline" and check "Set On Boot"

Tuesday, November 9, 2010

Booting Galaxy S to Recovery Mode

  • Turn off the device
  • Press and hold Volume Up + Home + Power buttons
  • On samsung splash/intro screen release the Power button while still holding the Home button
  • Use the Volume Up and Down buttons to navigate to the Recovery mode in the list

Tuesday, September 28, 2010

Samsung Galaxy S is now available in stores other than Globe Telecom

At last Samsung Galaxy S is now available in store other than Globe Telecom

Samsung Galaxy S (GT-I9000) authorized stores

Store NameAddressContact Number
BSD International 4th Level Bldg. B, SM Megamall(02)631-1276
BSD International E-Com Center Harbor SM Mall of Asia(02)804-0526
Memo ExpressSM North EDSA Annex(02)332-6454, 332-6471