Thursday, June 13, 2013

Steps to move Symfony 2 project to hosting?

Steps to move Symfony 2 project to hosting?

 

Altenative 1

First the httpd.conf file MUST be changed to reference /sites/dir/website/web directory as the DocumentRoot directory, all other files such as lib and config must not be accessible over the web.

 

Altenative 2

 

  1. It depends on kind of hosting that you have: if you have SSH console, then you can do it on hosting after step 2, if you haven`t than do it localy: run command 'php app/console cache:clear --env=prod'.
  2. Suppose you have on you hosting folders youdomain/public_html, so in public_html must be located all web files. So you must upload all from symfony project (folders: app,src,vendors, bin; files: deps, deps.lock), except folder 'web' in folder 'youdomain'. Everuthing from folder 'web' upload to folder public_html.
  3. Check CHMOD for folders app/cache and app/logs, there should be write access.
  4. If there is no file .htaccess in public_html, then create it and add such code in it: https://raw.github.com/symfony/symfony-standard/master/web/.htaccess
  5. Now you should use youdomain.com/index instead of youdomain.com/app_dev.php/index, that you use locally. If site still did not works, you can open file web/config.php and find code where perform check for IP, you find there only ip 127.0.0.1, add your current ip to this list and upload new config on server. Then you can open path yourdomain/config.php and check what`s wrong. If config.php shows that everything ok, but still didn't work, you can enable app_dev.php to debug: open app/app_dev.php and your ip as for config.php. Now you can run scripts as localy using app_dev.php.

 

 

Alternative3

 

I got it to work, this is my experience:
  • Upload the whole project folder to the server.
  • Enter www.your-website.com/project-name/web/config.php.
  • It should say: "This script is only accessible from localhost".
  • Open this web site: http://www.whatismyip.com, it should show you your public IP address, copy it.
  • Open the config.php from the admin panel (like cPanel) and edit that config.php:

if (!in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1', /*your IP here*/))) {
    header('HTTP/1.0 403 Forbidden');
    die('This script is only accessible from localhost.');  
}

  • Refresh your config.php file, the page will tell you if your system is missing some required conditions like: PHP version, APC extension, giving /cache and /log folders permissions to write on, etc.
  • After you provide the required conditions you'll see a form of configuring you project to connect to a database if you have one, this step is pretty simple.
  • Open the link www.your-website.com/project-name/web/app_dev.php, it'll help you get started with Symfony2 project.
  • In case you got in app_dev.php this message: You are not allowed to access this file... just do the same thing to app_dev.php as you did in steps 4 and 5 (add your public IP address to the array).
    Note of Hakan Deryal (comment): If you don't have a fix IP address, you need to do this last step each time you get a new IP adrdress from the DHCP. So to solve that, open the app_dev.php and comment out the line die('You are not allowed to.., however this is not a recommended way because you're disabling the built-in security of the file.
  • One thing stopped me and may stop you too, the server I deployed the project on, was case-sensitive (unlike the localhost on my computer), so it kept telling me that the template (Index.html.php for example) does not exist, however it does exist, but I did return $this->render('...:index.html.php') with small i in DefaultController.php. So render the exact template (file) name with the same letters cases.
Now everything is going well, I hope that helps you.

 

Thursday, June 6, 2013

Paginator Bundle :: KnpPaginatorBundle

1. Installation
    -add to composer.json

{
    "require": {
        "knplabs/knp-paginator-bundle": "dev-master"
    }
}
 
 
2. configure
  - add app/config/config.yml
 
knp_paginator:
    page_range: 5                      # default page range used in pagination control
    default_options:
        page_name: page                # page query parameter name
        sort_field_name: sort          # sort field query parameter name
        sort_direction_name: direction # sort direction query parameter name
        distinct: true                 # ensure distinct results, useful when ORM queries are using GROUP BY statements
    template:
        pagination: KnpPaginatorBundle:Pagination:sliding.html.twig     # sliding pagination controls template
        sortable: KnpPaginatorBundle:Pagination:sortable_link.html.twig # sort link template
 
 
  3. Add to application kernel
   - add  app/AppKernel.php

public function registerBundles()
{
    return array(
        // ...
        new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(),
        // ...
    );
} 
 
 
 
 
 
The controller :
 
 
        $em    = $this->get('doctrine.orm.entity_manager');
        $dql   = "SELECT a FROM ASFPembedaBundle:Quran a WHERE a.sura = '$surah'";
        $query = $em->createQuery($dql);

        $paginator  = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
           $query,
           $this->get('request')->query->get('page', 1)/*page number*/,
           10/*limit per page*/
        );


        return $this->render('ASFPembedaBundle:Quran:qsurah.html.twig', array(
            'pagination' => $pagination,
            'comments'  => 'ssssss'
        ));
 
 
The view :
 
   <table border=1>
   {# table body #}
   {% for ayat in pagination %}
         <tr {% if loop.index is odd %}class="snippet"{% endif %}>
            <td>{{ ayat.aya }}</td><td>{{ ayat.text }}</td>
         </tr>
         <tr {% if loop.index is odd %}class="grey"{% endif %}>
            <td></td><td>
            <div>
               <p>{{ ayat.quranmakna.mtext }}</p>
            </div>
            </td>
         </tr>
         
    {% else %}
        <p>Search text not found</p>
    {% endfor %}
</table>
   
{# display navigation #}
<div class="navigation">
    {{ knp_pagination_render(pagination) }}
</div> 
 

Unknown database type enum requested ...

Installing the FOSuser and get error after the below step command :

php app/console doctrine:schema:update --force


[Doctrine\DBAL\DBALException]                                               
  Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform 
   may not support it.


doctrine:schema:update [--complete] [--dump-sql] [--force] [--em[="..."]]


vi app/config/config.app

add :

mapping_types:
    enum: string
 
 
to the doctrine:dbal:
 
like this : 
 
 
doctrine:
    dbal:
        driver: %database_driver%
         host: %database_host%
         port: %database_port%
         dbname: %database_name%
         user: %database_user%
         password: %database_password%
         charset: UTF8
         mapping_types:
             enum: string 

Wednesday, June 5, 2013

Login Bundle :: FOSUser

ref : https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#LNaN

Install login bundle :

Step 1:  edit composer.json

{
    "require": {
        "friendsofsymfony/user-bundle": "~2.0@dev"
    }
}

Step 2:  download
php composer.phar update friendsofsymfony/user-bundle
 

Step 3:  Enable bundle, edit app/AppKernel.php
 
<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new FOS\UserBundle\FOSUserBundle(),
    );
}
 
  
Step 4:  Creating User Class

<?php 
// src/ASF/PembedaBundle/Entity/User.php

namespace ASF\PembedaBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
}
 
 
Step 5: Configure your application's security.yml
 
 
# app/config/security.yml
security:
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
            logout:       true
            anonymous:    true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN } 
 
 
Step 6: Configure the FOSUserBundle
 
 # app/config/config.yml
fos_user:
    db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
    firewall_name: main
    user_class: ASF\PembedaBundle\Entity\User
 
Step 7: Import FOSUserBundle routing files



# app/config/routing.yml
fos_user_security:
    resource: "@FOSUserBundle/Resources/config/routing/security.xml"

fos_user_profile:
    resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
    prefix: /profile

fos_user_register:
    resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
    prefix: /register

fos_user_resetting:
    resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
    prefix: /resetting

fos_user_change_password:
    resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
    prefix: /profile


Step 8: Update your database schema


php app/console doctrine:schema:update --force
 
You now can login at http://symfony/app_dev.php/login 


Tuesday, May 28, 2013

Template : Twig - Basic

Variables
 {{foo.bar}}
 {{foo['bar']}}


Global Variables
  _self : references the current template;
  _context : references the current context;
 _charset : references the current charset

Setting Variables
 {% set foo = 'foo' %}
 {% set foo = [1,2] %}
 {% set foo = { 'foo' : 'bar' } %}

Filters
  {{ name|striptags|title }}

  {{ list|join(', ') }}
  {% filter upper %}  
         This text becomes uppercase  
  {% endfilter %}

   built-in filter :
   abs / batch / capitalize / convert_encoding / date / date_modify / default /
   escape / first / format / join / json_encode / keys / last / length / lower / nl2br /
   number_format / merge / upper / raw / replace / reverse / slice / sort / split /
   striptags / title / trim / url_encode  


Functions
 {% for i in range(0, 3) %}
        {{ i }},  
 {% endfor %}

  built-in function :
   attribute / block / constant / cycle / date / dump /
   include / parent / random / range / template_from_string

{% for i in range(low=1, high=10, step=2) %}
    {{ i }},
{% endfor %}
 
 {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
 
 {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}






Control Structure

<ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
</ul>
 
{% for i in 0..10 %}
    * {{ i }}
{% endfor %}
 
{% for letter in 'a'..'z' %}
    * {{ letter }}
{% endfor %} 
 
{% for letter in 'a'|upper..'z'|upper %}
    * {{ letter }}
{% endfor %} 
 
 
   for tags :
 



{% if users|length > 0 %}
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
{% endif %}


{% if online == false %}
    <p>Our website is in maintenance mode. Please, come back later.</p>
{% endif %} 
 
 
{% if users %}
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
{% endif %}


 
 
 
 
Including other Templates
 
 {% include 'sidebar.html' %} 
 
 {% for box in boxes %}
    {% include "render_box.html" %}
{% endfor %}


 

{% include "sections/articles/sidebar.html" %}



Template Inheritance (block)

base.html (4 block)

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css" />
            <title>{% block title %}{% endblock %} - My Webpage</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">{% block content %}{% endblock %}</div>
        <div id="footer">
            {% block footer %}
                &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
            {% endblock %}
        </div>
    </body>
</html>
 
 Child tepmalte :
 
{% extends "base.html" %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
        Welcome to my awesome homepage.
    </p>
{% endblock %}
 
 
extends - using parent() function
 
{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ parent() }}
{% endblock %} 
 
 


HTML Escaping (using piping)

{{ user.username|escape }} 
{{ user.username|e }}

{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}

{% autoescape %}
    Everything will be automatically escaped in this block (using the HTML strategy)
{% endautoescape %}
 
{{ '{{' }}

{% macro input(name, value, type, size) %}
    <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
{% endmacro %}

{% import "forms.html" as forms %}
<p>{{ forms.input('username') }}</p>


{% from 'forms.html' import input as input_field %}

<dl>
    <dt>Username</dt>
    <dd>{{ input_field('username') }}</dd>
    <dt>Password</dt>
    <dd>{{ input_field('password', '', 'password') }}</dd>
</dl>


{% macro input(name, value = "", type = "text", size = 20) %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
{% endmacro %}



Expressions
 operator precedence :
  b-and, b-xor, b-or, or, and, ==, !=, <, >, >=, <=, in, .., +, -, ~, *, /, //, %, is, **, |, [], and .:


{% set greeting = 'Hello' %}
{% set name = 'Fabien' %}

{{ greeting ~ name|lower }}   {# Hello fabien #}

{# use parenthesis to change precedence #}
{{ (greeting ~ name)|lower }} {# hello fabien #}


{# keys as string #}
{ 'foo': 'foo', 'bar': 'bar' }

{# keys as names (equivalent to the previous hash) -- as of Twig 1.5 #}
{ foo: 'foo', bar: 'bar' }

{# keys as integer #}
{ 2: 'foo', 4: 'bar' }

{# keys as expressions (the expression must be enclosed into parentheses) -- as of Twig 1.5 #}
{ (1 + 1): 'foo', (a ~ 'b'): 'bar' }


{% set foo = [1, {"foo": "bar"}] %}

Math

 + : {{ 1 + 1 }} is 2. 
 - : {{ 3 - 2 }} is 1. 
 / : The returned value will be a floating point number. {{ 1 / 2 }} is {{ 0.5 }}. 
 % : {{ 11 % 7 }} is 4. 
 //: Divides and returns the truncated integer result. {{ 20 // 7 }} is 2. 
 * : {{ 2 * 2 }} would return 4. 
 **: power of the right operand. {{ 2 ** 3 }} would return 8.

Logic

 and , or , not , (expr)


Comparisons

==, !=, <, >, >=, and <=



Containment Operator

{# returns true #}
{{ 1 in [1, 2, 3] }}

{{ 'cd' in 'abcde' }}
 
{% if 1 not in [1, 2, 3] %}

{# is equivalent to #}
{% if not (1 in [1, 2, 3]) %}

Test Operator

{# find out if a variable is odd #}
{{ name is odd }}
{% if loop.index is divisibleby(3) %} 
{# is equivalent to #}
{% if not (loop.index is divisibleby(3)) %}


Other Operators
  ..    :  range 
  |    : Applies a filter. 
  ~      : Converts into strings and concat. 
  ., [] : Gets an attribute of an object. 
  ?:    : The ternary operator


{{ foo ? 'yes' : 'no' }}

{# as of Twig 1.12.0 #}
{{ foo ?: 'no' }} == {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} == {{ foo ? 'yes' : '' }}

String Interpolation

{{ "foo #{bar} baz" }}
{{ "foo #{1 + 2} baz" }}

Whitespace Control


{% spaceless %}
    <div>
        <strong>foo</strong>
    </div>
{% endspaceless %}

{# output will be <div><strong>foo</strong></div> #} 
 
{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# output 'no spaces' #}
 
{% set value = 'no spaces' %}
<li>    {{- value }}    </li>

{# outputs '<li>no spaces    </li>' #} 
 
 
 









Global Tempalate :

  • app.security - The security context.
  • app.user - The current user object.
  • app.request - The request object.
  • app.session - The session object.
  • app.environment - The current environment (dev, prod, etc).
  • app.debug - True if in debug mode. False otherwise.

Friday, May 24, 2013

Data Fixtures : Untuk insert data dalam table dengan segera.

Tambah vendor bundel

edit composer.json  // nak download yang latest

tambah :

"require": {
    // ...
    "doctrine/doctrine-fixtures-bundle": "dev-master",
    "doctrine/data-fixtures" : "dev-master"
}
 
run : 
 
php composer.phar update 

register bundle dekat

// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
        // ...
    );
    // ...
}



Create a fixture file di src/ASF/PembedaBundle/DataFixtures/ORM/SurahFixtures.php

// src/ASF/PembedaBundle/DataFixtures/ORM/SurahFixtures.php

namespace ASF\PembedaBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use ASF\PembedaBundle\Entity\Surah;

//class SurahFixtures implements FixtureInterface
class SurahFixtures extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $surah1 = new Surah();

       $surah1->setId('001');
       $surah1->setIndex(1);
       $surah1->setBilayat(7);
       $surah1->setMulaayat(0);
       $surah1->setNama("الفاتحة");
       $surah1->setTnama('Al-Faatihah');
       $surah1->setEnama('The Opening');
       $surah1->setMnama('Pembukaaan');
       $surah1->setCategory('Mekah');
       $surah1->setOrder(5);
       $surah1->setRukus(1);
       $surah1->setPengenalan('');
       $surah1->setImage('alquran.jpg');
       $surah1->setTags('jalan, iman, islam');
       $surah1->setCreated(new \DateTime());
       $surah1->setUpdated($surah1->getCreated());
       $manager->persist($surah1);

       $surah2->setId('002');
       $surah2->setIndex(2);
       $surah2->setBilayat(286);
       $surah2->setMulaayat(7);
       $surah2->setNama("البقرة");
       $surah2->setTnama('Al-Baqara');
       $surah2->setEnama('The Cow');
       $surah2->setMnama('Lembu Betina');
       $surah2->setCategory('Madinah');
       $surah2->setOrder(87);
       $surah2->setRukus(40);
       $surah2->setPengenalan('');
       $surah2->setImage('alquran.jpg');
       $surah2->setTags('jalan, iman, islam');
       $surah2->setCreated(new \DateTime());
       $surah2->setUpdated($surah2->getCreated());
       $manager->persist($surah2);
        $manager->flush();

        $this->addReference('surah-1', $surah1);
        $this->addReference('surah-2', $surah2);
}


loading the fixtures to database
php app/console doctrine:fixtures:load

Symfony CLI


 
 
- To create getters & setters from entity 
php app/console doctrine:generate:entities ASF
 
- To create database from app/config/parameters.ini 
php app/console doctrine:database:create 
 
- To create table from entity file
php app/console doctrine:schema:create
 
-To copy asset to production asset
php app/console assets:install web
 
 - To clear cache
php app/console cache:clear --env=prod 
php app/console cache:clear --env=dev 
php app/console cache:clear --env=test
 
 - To update table
php app/console doctrine:schema:update --force
 
 
 - To update fixture
php app/console doctrine:fixtures:load