Thursday, December 10, 2015

How to print out the real sql in Doctrine and Symfony?

Doctrine is not sending a "real SQL query" to the database server : it is actually using prepared statements, which means :
- Sending the statement, for it to be prepared (this is what is returned by $query->getSql();)
- And, then, sending the parameters (returned by $query->getParameters();)
- and executing the prepared statements
Show SQL: $sql=$query->getSQL();

Show Parameters: $parameters=$query->getParameters();
In this way, you can generate or print the real sql using Doctrine and Symfony. In my opinion, It will be much easy to debug the errors in the real sql than doctrine prepared query.
Source : http://stackoverflow.com/a/2095467

Friday, November 27, 2015

Passing Array of Conditions To doctrine expr()->orx()

Problem
I needed to construct DQL with a QueryBuilder like this in one of my Symfony project.
[QUERY]... AND WHERE e.type = x OR e.type = Y OR e.type = N [...]
I have list of types in the array but was confused on how to pass the dynamic array to my query builder. List of types will be dynamic.
$qb->andWhere($qb->expr()->orx(CONDITIONS));

Solution:
After some research, I found out about $orX->addMultiple($conditions) method and it fixed my problem.
First I built array of condition using foreach loop and then passed that condition array inside addMultiple method and finally passed orx variable inside addWhere method.
You can build array of condition using foreach like below.
/* $conditions = array('e.type = x', 'e.type = Y', 'e.type = N'); */


foreach($types as $type)
{
   $conditions[] = $qb->expr()->eq('e.type', ':' . $type . '_value');
   $qb->setParameter($type . '_value', $type);
}

 $orX = $qb->expr()->orX();
 $orX->addMultiple($conditions);
 $qb->andWhere($orX);
In this way you can store multiple orx expressions and then add it to andWhere.

Ref: http://stackoverflow.com/a/32250191

Wednesday, November 18, 2015

Fetching Objects from the Database using Doctrine and Symfony

CRUD stands for Create, Read, Update and Delete, the basic operations performed on the database. In this article, I will show you how to perform C(R)UD with Doctrine.

In Doctrine and Symfony, there are multiple ways of accomplishing the same task. This gives you flexibility to pick the best approach suitable for each situation. Therefore we shall explore these different methods for each method of the fetching and object(i.e Read in CRUD).

The act of fetching records/object from the database is very easier using doctrine. Most of these are performed on Doctrine_Table objects, which is obtained by $this->getDoctrine()->getRepository() and passing the model class name to it. When you query for a particular type of object, you always use what's known as its repository.
$repository = $this->getDoctrine()
    ->getRepository('AppBundle:Product');
The AppBundle:Product string is a shortcut you can use anywhere in Doctrine instead of the full class name of the entity (i.e. AppBundle\Entity\Product). As long as your entity lives under the Entity namespace of your bundle, this will work.

Once you have your repository, you have access to all sorts of helpful methods:
find()
The find() method fetches a record by the Primary Key value.
// query by the primary key (usually "id")
$product = $repository->find($id);

findOneBy*()
This is a magic method. You can simply append the column name, and it will search the table by that column.
// dynamic method names to find based on a column value
$product = $repository->findOneByName('foo');
You can also take advantage of the useful findOneBy method to easily fetch objects based on multiple conditions:
// query for one product matching by name and price
$product = $repository->findOneBy(
    array('name' => 'foo', 'price' => 19.99)
);
It fetches only one record.

findBy*()
Another magic method, which works similarly, but fetches multiple rows. It returns a Doctrine_Collection object.
// find a group of products based on an arbitrary column value
$products = $repository->findByPrice(19.99);
You can also take advantage of the useful findBy method to easily fetch objects based on multiple conditions:
// query for all products matching the name, ordered by price
$products = $repository->findBy(
    array('name' => 'foo'),
    array('price' => 'ASC')
);

DQL
It stands for Doctrine Query Language. It is actually a major feature. Most advanced queries are performed using DQL. You can use Doctrine's native SQL-like language called DQL to make a query for this:
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
    'SELECT p
    FROM AppBundle:Product p
    WHERE p.price > :price
    ORDER BY p.price ASC'
)->setParameter('price', '19.99');

$products = $query->getResult();
// to get just one result:
// $product = $query->setMaxResults(1)->getOneOrNullResult();
If you're comfortable with SQL, then DQL should feel very natural. The biggest difference is that you need to think in terms of "objects" instead of rows in a database. For this reason, you select from the AppBundle:Product object (an optional shortcut for AppBundle\Entity\Product) and then alias it as p.
The getResult() method returns an array of results. To get only one result, you can use getOneOrNullResult():
$product = $query->setMaxResults(1)->getOneOrNullResult();

Doctrine's Query Builder
Instead of writing a DQL string, you can use a helpful object called the QueryBuilder to build that string for you. This is useful when the actual query depends on dynamic conditions, as your code soon becomes hard to read with DQL as you start to concatenate strings:
$repository = $this->getDoctrine()
    ->getRepository('AppBundle:Product');

// createQueryBuilder automatically selects FROM AppBundle:Product
// and aliases it to "p"
$query = $repository->createQueryBuilder('p')
    ->where('p.price > :price')
    ->setParameter('price', '19.99')
    ->orderBy('p.price', 'ASC')
    ->getQuery();

$products = $query->getResult();
// to get just one result:
// $product = $query->setMaxResults(1)->getOneOrNullResult();
The QueryBuilder object contains every method necessary to build your query. By calling the getQuery() method, the query builder returns a normal Query object, which can be used to get the result of the query.
Source: http://symfony.com/doc/current/book/doctrine.html#querying-for-objects

Friday, November 13, 2015

How To TRUNCATE TABLE With Symfony And Doctrine?

There are two possibilities for bulk deletes with Doctrine. You can either issue a single DQL DELETE query or you can iterate over results removing them one at a time.

Example of single DQL Delete query:
 $em = $this->getDoctrine()->getManager();
 $em->createQuery('DELETE FROM AppBundle\Entity\Customer')->execute();

It is very simple to truncate or empty the table from mysql using Symfony and Doctrine.

Note: If you have relations you should be careful to handle the linked entities.
Ref: http://doctrine-orm.readthedocs.org/en/latest/reference/batch-processing.html#dql-delete

Wednesday, November 4, 2015

How To Upload Image To Remote Server With cURL And PHP?

If you want to upload images to an external server which is uploaded to your site by a client, you are at the right tutorial.

cURL can do just about anything that a normal web browser can do including send a file via a post request.

CurlFile should be used to upload files with CURLOPT_POSTFIELDS. The curl API will be modified to look for objects of type CurlFile. The file given to CurlFile will not be opened/read until curl_setopt() call.

Alternative 1: Send a file with php/cURL via POST using absolute file uploaded path
$file_name_with_full_path = realpath('./upload/example.png');
 
$curl_handle = curl_init("https://example.com");
 
curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = new CurlFile($file_name_with_full_path, 'image/png');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args); 
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);

 
//execute the API Call
$returned_data = curl_exec($curl_handle);
curl_close ($curl_handle);

echo $returned_data;


Alternative 2: Send a file with php/cURL via POST using form file field: Without CurlFile file uploading function
//index.php
<?php
if(isset($_POST['check_submit']))
{ 
    $tmpfile = $_FILES['assets']['tmp_name'];
    $filename = basename($_FILES['assets']['name']); 
    $filetype = $_FILES['assets']['type']; 
    
/* 
As the @ format is now deprecated. Use curl_file_create function instead as below
       $POST_DATA = array(
   'file' => '@'.$tmpfile.';filename='.$filename
  );
*/

    $POST_DATA = array(
   'file' => curl_file_create($tmpfile, $filetype, $filename)
  );

    // Connecting to external api via cURL
    $curl_handle = curl_init("https://example.com");  
    curl_setopt($curl_handle, CURLOPT_POST, 1);
    curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $POST_DATA); 
    curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
   
    //execute the API Call
    $returned_data = curl_exec($curl_handle);
    curl_close ($curl_handle);
 
    echo $returned_data;
}
?>


<form method="POST" action="" enctype="multipart/form-data">

<p>Select a file to upload : </p>

<input type="file" name="assets">

<input type="submit" name="check_submit"/>

</form>

This API is both inconvenient and insecure, it is impossible to send data starting with '@' to the POST, and any user data that is being re-sent via cURL need to be sanitized so that the data value does not start with @. In general, in-bound signalling usually vulnerable to all sorts of injections and better not done in this way.

Instead of using the above method, the following (Alternative 3) should be used to upload files with CURLOPT_POSTFIELDS:

Alternative 3: Send a file with php/cURL via POST using form file field: Recommended
Screenshot:
//index.php
<?php
if(isset($_POST['check_submit']))
{ 
    $tmpfile = $_FILES['assets']['tmp_name'];
    $filename = basename($_FILES['assets']['name']); 
    $filetype = $_FILES['assets']['type']; 

    // Connecting to external api via cURL
    $curl_handle = curl_init("https://example.com");  
    curl_setopt($curl_handle, CURLOPT_POST, 1);
    $args['file'] = new CurlFile($tmpfile, $filetype, $filename);
    curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args); 
    curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
   
    //execute the API Call
    $returned_data = curl_exec($curl_handle);
    curl_close ($curl_handle);
 
    echo $returned_data;
}
?>

<form method="POST" action="" enctype="multipart/form-data">

<p>Select a file to upload : </p>

<input type="file" name="assets">

<input type="submit" name="check_submit"/>

</form>
The important function to handle file post via curl is CurlFile function. The syntax of CurlFile function is shown below:
/**
* @param string $name File name
* @param string $mimetype Mime type, optional
* @param string $postfilename Post filename, defaults to actual filename
*/
$args['file'] = new CurlFile($name, $mimetype = '', $postfilename = '');

Ref: https://wiki.php.net/rfc/curl-file-upload
http://php.net/manual/en/class.curlfile.php
http://stackoverflow.com/a/29122849

Wednesday, October 28, 2015

Declare Array of Arrays And Convert To JSON Using PHP

Here is the array of arrays declaration.
$data = array(
  'title' => 'Title',
  'name' => 'Name',
  'comments' => array(
               0 => array(
                      'name' => 'John Doe',
                      'email' => 'john@example.com'
                      ),
               1 => array(
                      'name' => 'Jane Doe',
                      'email' => 'jane@example.com'
                      ),

              )
 );
JSON output using json_encode() function of PHP
{
 title: 'Title',
 name: "Name",
 comments: [
 {
  name: "John Doe",
  email: "john@example.com"
 },
 {
  name: "Jane Doe",
  email: "jane@example.com"
 }
 ]
}

Monday, October 26, 2015

How To Convert SQL Into DQL in Symfony and Doctrine?

Today I am going to talk about some examples on converting SQL queries into DQL . Doctrine query language (DQL) is the query language used by Doctrine ORM. Doctrine ORM 2.x is shipped with Symfony 2.x by default. Let’s take some examples and discuss. For the following examples we will be creating an instance of Doctrine query builder to structure DQL’s.

Creating an instance of doctrine query builder
$em = $this->getDoctrine()->getManager();
$result = $em->createQueryBuilder();
SQL
SELECT * FROM contact
DQL
$dql = $result->select(‘c’)
->from(‘ACMETestBundle:Contact’, ‘c’)
->getQuery();
In the above dql example inside ‘from’ tag you have to mention the fully qualified name of the entity which represents the contact table. I am taking a the result as a doctrine object. But if you want to get the results as an array instead of the doctrine object, you can add this line at the end of the code.
$dql = $result->select(‘c’)
->from(‘ACMETestBundle:Contact’, ‘c’)
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
Sometimes you want to see whether dql returns the correct sql or not. So, in that case you would like to return the relevant sql for the given dql. To do that you can add following piece of code after getQuery() tag.
$dql = $result->select(‘c’)
->from(‘ACMETestBundle:Contact’, ‘c’)
->getQuery()
->getSQL();
Assume you want to convert a sql which contains one or few where conditions in to dql.
SQL
SELECT * FROM contact WHERE first_name = ‘david’ AND last_name = ‘john’;
DQL
$dql = $result->select(‘c’)
->from(‘ACMETestBundle:Contact’, ‘c’)
->where(‘c.first_name = :fName’)
->setParameter(‘fName’, $firstName)
->andWhere(‘c.last_name = :lName’)
->setParameter(‘lName’, $lastName)
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
Remember the best practice is we don’t give the where condition as this ‘->where(‘c.first_name = ” ‘. $firstName.’ ” ‘ )’, which is wrong. We always pass the variable inside setParameter() method, which is sql safe. If you want to perform ‘first_name LIKE ‘%david%’ . You can alter above where and set parameter statements like this.
->where(‘c.first_name LIKE :fName’)
->setParameter(‘fName’, ‘%’.$firstName.’%’)
If you want to perform ‘OR’ condition in where instead of ‘AND’ you just use ‘orWhere()’ instead of ‘andWhere’.
In a situation where you would like to perform a JOIN such as LEFT JOIN there are two ways you can do it. If you have already mentioned the relationships (such as oneToOne, oneToMany) in orm.yml files you can easily perform the LEFT JOIN like this,
SQL
SELECT c, p FROM contact c LEFT JOIN person p ON p.contact_id = c.id
DQL
$dql = $result->select(‘c’,’p’)
->from(‘ACMETestBundle:Contact’, ‘c’)
->leftJoin(‘c.person’, ‘p’)
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
But, if you want to perform the LEFT JOIN relationship when you query (if you haven’t set the necessary relationships at first place), you can do the same like this manner,
$dql = $result->select(‘c’,’p’)
->from(‘ACMETestBundle:Contact’, ‘c’)
->leftJoin(‘c.person’, ‘p’, \Doctrine\ORM\Query\Expr\Join::ON, ‘p.contact_id = c.id’)
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
Inside ‘leftJoin’ tag you need to give name of the table unlike fully qualified entity name we gave inside ‘from’ tag.

Well, that’s it for today. I hope you guys had a better understanding about converting SQLs into DQLs.

Cheers!
Source: http://anjanasilva.com/blog/sql-into-dql-examples-symfony-2-doctrine-2/

Friday, October 23, 2015

Difference Between $this->renderView and $this->render in Symfony2

renderView(): Returns a rendered view.
render(): It renders full HTTP response (with headers) and returns a Response object (with the rendered template, headers, etc).

For example:
If you have a controller action that generates an XML file from a twig template using render() and serves it to clients like this :
$response = new Response();
$response->setContent($this->render('MyBundle:Formation:feed.xml.twig',
  array('formation' => $formation);
$response->headers->set('Content-Type', 'text/xml');
 
return $response;

but when you save the file on the browser side, It will contain the HTTP headers :
HTTP/1.0 200 OK
Cache-Control: no-cache
Date:          Tue, 18 Oct 2015 12:04:39 GMT

<?xml version="1.0" encoding="UTF-8"?>
(...)
In order to get rid of these headers in the downloaded XML file, you should use renderView() method,
$response = new Response();
$response->setContent($this->renderView('MyBundle:Formation:feed.xml.twig',
  array('formation' => $formation);
$response->headers->set('Content-Type', 'text/xml');
 
return $response;

Wednesday, October 14, 2015

How To Add a Column To an Existing Entity in Symfony?

As you want to keep your customers/peers updated with the latest version of the model, you should use the Doctrine Migrations. That's the way to manage database updates. Moreover, it gives you complete control on what to do when upgrading/downgrading the database.

The steps for adding a new property/column on the entity class are:

1. Add the property you want eg. On User Entity class
    UserBundle\Entity\User

2. Run the following console command 
    php app/console doctrine:generate:entities UserBundle:User

- It will add the proper getter/setter in the entity class.

3. Run the following console command  
    php app/console doctrine:migrations:diff

- It will generate a migration by comparing your current database to your mapping information and place a new migration file on app/Migrations/.

4. Run the following console command 
    php app/console doctrine:migrations:migrate

- It will execute a migration to a specified version or the latest available version.

Source: http://stackoverflow.com/a/14942242

Tuesday, October 13, 2015

How To Fix Doctrine PDOException No such file or directory in Symfony?

I had issue when I tried to migrate the DB schema via command line.
php app/console doctrine:migrations:migrate --env=test
I got following errors.
[Doctrine\DBAL\Exception\ConnectionException]                                     
  An exception occured in driver: SQLSTATE[HY000] [2002] No such file or directory 

[Doctrine\DBAL\Driver\PDOException]               
  SQLSTATE[HY000] [2002] No such file or directory

 [PDOException]                                    
  SQLSTATE[HY000] [2002] No such file or directory 

Solution:
Open parameters.yml and check for host. If it is stand localhost then replace host as follows:
 'host'=> 'localhost' to 'host'=> '127.0.0.1'
If it didn't solve your problem then do following steps:
Assuming Mysql database settings are correctly inserted in the config/parameters.yml file.
And open the Doctrine configuration in config/config.yml and add the following line
unix_socket: /Applications/MAMP/tmp/mysql/mysql.sock after password as below.
# Doctrine Configuration
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   "%database_driver%"
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   "%database_name%"
                user:     "%database_user%"
                password: "%database_password%"
                unix_socket: "/Applications/MAMP/tmp/mysql/mysql.sock"
                charset:  UTF8
This solved my problem.
The problem is the mysql.default_socket setting in PHP.INI defaults to a different location than where MySQL actually puts that file.
Instead of editing the config files, I created an alias in the location that PHP is looking that connects to the real mysql.sock.
mkdir /var/mysql
ln -s /Applications/MAMP/tmp/mysql/mysql.sock /var/mysql/mysql.sock

Ref: http://stackoverflow.com/a/26436016
http://andreys.info/blog/2007-11-07/configuring-terminal-to-work-with-mamp-mysql-on-leopard

Friday, October 9, 2015

How To Customize 404 Error Page In Symfony 2?

In Symfony applications, all errors are treated as exceptions, no matter if they are just a 404 Not Found error or a fatal error triggered by throwing some exception in your code.

To override the 404 error template for HTML pages, create a new error404.html.twig template located at app/Resources/TwigBundle/views/Exception/:
{# app/Resources/TwigBundle/views/Exception/error404.html.twig #}
{% extends 'base.html.twig' %}

{% block body %}
    <h1>Page not found </h1>
    {{ exception.message }}
    <p>
        The requested page couldn't be located. Checkout for any URL
        misspelling or <a href="{{ path('homepage') }}">return to the homepage</a>.
    </p>
{% endblock %}
You can access your detected text with following way:
{{ exception.message }}
If error404.html.twig template is not created, then it will fall back to the generic HTML template app/Resources/TwigBundle/views/Exception/error.html.twig.

Do not forget to clear the cache after saving the error404.html.twig template. You can clear cache via
$ php app/console cache:clear

//to clear cache in production environment
$ php app/console cache:clear --env:prod
You can read more detail about How to customize error pages in Symfony 2 => How to Customize Error Pages

Monday, October 5, 2015

How To Fix date_default_timezone_get() Warning While Installing Symfony?

I am using MAMP for my server and symfony 2.7.5.
I want to generate bundle with command line. But I have this Exception error on my console:
[Symfony\Component\Debug\Exception\ContextErrorException]                    
Warning: date_default_timezone_get(): It is not safe to rely on the system's 
timezone settings. You are *required* to use the date.timezone setting or  
the date_default_timezone_set() function. In case you used any of those methods 
and you are still getting this warning, you most likely misspelled the 
timezone identifier. We selected 'UTC' for 'CEST/2.0/DST' instead 
......

Solution
1. Check date.timezone parameter in php.ini file (MAMP/bin/php/php5.5.18/conf/php.ini) and uncomment (remove this symbol ';' from beginning of the string) and set as follows

   date.timezone = "Europe/Berlin"

2. If the problem is still there, check where the CLI php.ini is located: 

   php -i | grep "php.ini"

In my case I ended up with : Configuration File (php.ini) Path => /etc

Then cd .. all the way back and cd into /private/etc/, do ls in my case php.ini didn't show up, only a php.ini.default

3. Now, copy the php.ini.default file named as php.ini:

  sudo cp php.ini.default php.ini

4. In order to edit, change the permissions of the file:

   sudo chmod ug+w php.ini

   sudo chgrp staff php.ini

5. Initialize configuration parameter date.timezone in your php.ini. You must open your php.ini with superuser privileges and edit the php.ini file:

   sudo mcedit /private/etc/php.ini 

   or nano /private/etc/php.ini

6. Search for [Date] and make sure the following line is in the correct format:

   date.timezone = "Europe/Berlin"

7. Save the changes and restart the server.

IT WORKED !!!
Ref: http://stackoverflow.com/a/26415168

Friday, September 4, 2015

Jolly Jumper Sequence Challenge Solved in PHP

Description
You are a spy and you need to frequently send the order in which various numbered bids for a contracts are currently ranked without it being obvious that you are sending out the official ranks. You choose to disguise the actual ranking by creating a new candidate set of numbers. The real rank will be the absolute difference between successive elements. A sequence of n > 0 integers is a candidate if the absolute values of the differences between successive elements take on all possible ranks 1 through n – 1. The definition implies that any sequence of a single integer is a candidate. Another program has generated many possible number sequences, so your goal is to process that file to determine if a sequences is a candidate or not. Examples: 1 2 6 3 5 is a candidate, because the absolute differences are 1, 4, 3, and 2, respectively. 1 2 6 3 6 is NOT a candidate because the absolute differences are 1, 4 3, and 3.

Input
Your program should read lines of text from standard input. Each line will contain an integer n < 100 followed by a list of n space separated integers.

Output
For each line of input, print to standard output 'Candidate' or 'Not a Candidate' using the criteria in this challenge.

Solution
What I understood by reading above description is the absolute differences between every two consecutive numbers should be a permutation (every number from 1 to N-1 appears exactly one time in it) of the numbers from 1 to N-1.
To be considered a 'Candidate', given array must contain atleast one value and should be greater than 0. Otherwise it will considered as 'Not a Candidate'.
Absolute values of differences will fail to cover the range of 1 to n-1 if any of the difference value is repeated or any of the difference will fall out side the range of 1 to n-1 and there will be no need to check for the numbers further.
/* Complete Sourcecode */
function isCandidate($given_array)
{ 
 if(empty($given_array))
 {
  return 'Not a Candidate';
 }
 
 
 $length_of_array = count($given_array);

 /* given array must contain at least one element and should contain value greater than 0 to be considered as valid candidate */
 if($length_of_array == 1)
 {
  if($given_array[0] > 0)
  {
   return 'Candidate';
  }
  else
  {
   return 'Not a Candidate';
  }
  
 }
 
 $diff = array();

 for($i = 0; $i < $length_of_array - 1; $i++)
 {
  $diff[] = abs($given_array[$i] - $given_array[$i+1]);
 }
 
 
 if(min($diff) <  1 || max($diff) >= $length_of_array)
 {
  return 'Not a Candidate';
 }
 
 
 if(!empty(array_has_duplicate($diff)))
 {
  return 'Not a Candidate';  
 }
  
  
 
 return 'Candidate';  
 
 
}

/* returns 1 if it has duplicate values in the array*/
function array_has_duplicate($array) {
     return count($array) !== count(array_unique($array));
}

print(isCandidate($given_array));

I have tested againt below provided arrays. It have passed all the input scenarios.
/* Assumed format of sample input are integers with space seprated i.e 1 2 6 3 5 */
//Reading input from STDIN
$handle = fopen("php://stdin","r");
$t = fgets($handle);
$given_array = explode(" ", trim($t));
fclose($handle);

        //$given_array  = array(1);
 //$given_array  = array();
        //$given_array  = array(2,5,1,3,4);
 //$given_array  = array(1,2,6,3,5);
 //$given_array  = array(1,2,6,3,6);
 $given_array  = array(5,1,4,2,-1,6);

Am I missing any thing? Please do let me know, if there is any flaw or suggestion to make it more better.

Friday, June 26, 2015

How To Disable Email Engines From Automatically Hyperlinking a URL?

You can turn automatic hyperlinking off easily by following method. There exist other techniques as well to disable email engines from automatically hyperlinking a URL.
There is a zero-width non-breaking space that I like to use: &#65279;
I place it in strategic places so that the URL does not get recognized as a URL, like so:
http&#65279;://www&#65279;domain.&#65279;com.
This strategy has worked for me across platforms and rendering clients. Its advantages are twofold:
1) It prevents the client from auto-rendering text as a link, and
2) Unlike other "non-breaking" zero-width space ascii codes (ie &#8302;), it wraps the entire URL if your URL happens to need it (instead of just the parts after the zero-width space).
It served my purpose of not allowing email clients to automatically make it a hyperlink.

Ref: http://stackoverflow.com/a/12397389

Thursday, June 4, 2015

How To Get URL And Extract URL Segments Using jQuery?

It is easy to get URL and extract the URL segments dynamically using jQuery.In the below example, I have shown how to get the URL dynamically or setting the URL statically and extract parts or segments of URL.
//Getting the URL dynamically
var url = $(location).attr('href');

//Setting the URL statically
var url = 'http://www.example.com/segment1/example.html';

// Getting the file name i.e last segment of URL (i.e. example.html)
var fn = url.split('/').reverse()[0];

// Getting the extension (i.e. html)
var ext = url.split('/').reverse()[0].split('.').reverse()[0];

// Getting the second last segment of URL (i.e. segment1)
var lm = url.split('/').reverse()[1];
In the above example split the string URL when find "/" (separator) and use reverse save it in an array. Then using the proper index, you can get any part of URL you need (in the above example, we retrieved file name (last segment of URL), extension of file and second last segment of URL).

There are many other ways to get URL and extract URL segments using jQuery. Do share if you have any other good ideas.

Wednesday, April 15, 2015

How To Implement Database Migrations with CodeIgniter?

Migrations give you the ability to keep your database across all environments the same without comprimising the data inside the database. Think it as a version control for your database schema. You should be doing this at all times especially when there are multiple developers so all developers don't need to worry about having the latest database table.

A feature that was added fairly recently (CodeIgniter 2.1.0) is Migrations. This is a useful Class that allows for you to create and manage your database structure through your code. Database migrations are a way of effectively versioning your database changes.

STEP BY STEP

• You first need to create your migrations folder, application/migrations/

• You need to create a file inside this new directory (i.e. application/migrations/) and the naming format has to start with your version number followed by the name of your class (make it is descriptive of the changes that you are making i.e. your first one might be: initial_schema). My first migration file was called: 001_initial_schema.php and my next one could be 002_alter_schema.php

001_initial_schema.php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Migration_Initial_schema extends CI_Migration {

 public function up()
 {
  
           $this->load->dbforge();

           $this->dbforge->add_field(array(
   'blog_id' => array(
    'type' => 'INT',
    'constraint' => 5,
    'unsigned' => TRUE,
    'auto_increment' => TRUE
   ),
   'blog_title' => array(
    'type' => 'VARCHAR',
    'constraint' => '100',
   ),
   'blog_description' => array(
    'type' => 'TEXT',
    'null' => TRUE,
   ),
  ));

             $this->dbforge->add_key('blog_id', TRUE);  
             $this->dbforge->create_table('blog');
 }

 public function down()
 {
           $this->load->dbforge();  
           $this->dbforge->drop_table('blog');
 }

  }
You'll notice that there are two functions (up and down) in this class. The up function is run when you upgrade to/past this version and likewise the down function is run if you downgrade your database (using the config file) below this version. Your down function will always do the reverse of what your up function does. Essentially restoring your database to the state that it was before that version was added.

• Once your first migration is complete, you simply need to open application/config/migrations.php and edit:
$config['migration_enabled'] = FALSE;
to:
$config['migration_enabled'] = TRUE;

A bit lower down in this same file you will see the configuration property called migration_version i.e. $config['migration_version'] = 1;
As you see here, you need to set migration_version every time you create a new migration file. This is how the system knows what the current database version should be for your site. When it recognises that you're running on a lower version than this it will upgrade your database through all the steps leading up to this version. So once you add a migration you would increase this version number to match.

• Last step! Almost there! Now we actually have to call the actual migration. You can create a simple controller called controllers/migrate.php, like the one displayed below, which when visited calls the migration library.
migrate.php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Migrate extends CI_Controller {

  public function index()
  {
    $this->load->library('migration');

    if ( ! $this->migration->current()) {
      show_error($this->migration->error_string());
    }
  }

}

So there you have it, you now have a version controlled database that can be rolled forwards/backwards whenever you want.

Adding a second schema (called '002_alter_schema.php') to the application/migrations you can see how the database can be procedurally altered.

if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Migration_Alter_schema extends CI_Migration {

  public function up()
  {

    $this->load->dbforge();

    $fields = array(
      'author_first_name VARCHAR(50) DEFAULT NULL',
      'author_last_name VARCHAR(50) DEFAULT NULL'
    );

    $this->dbforge->add_column('blog', $fields);
  }

  public function down()
  {
    
    $this->load->dbforge();

    $this->dbforge->drop_column('blog', 'author_first_name');
    $this->dbforge->drop_column('blog', 'author_last_name');
  }
}

Looking at the above two migration examples, switching between versions is very simple. The simplicity comes from the creation of well thought out tear up (creation) and tear down (deletion) methods.

Don't forget to check on backend mysql table migrations to ensure that which version is currently active.

P:S: You can only have one migration file per version. Currently you have to create all the tables in one single file. The issue can arise when multiple developers maintaining different parts of the application.

Ref: http://robertsettle.com/2012/07/codeigniter-migrations/, http://eddmann.com/posts/database-migrations-with-codeigniter/, http://stevenlu.com/posts/2012/04/28/using-codeigniter-migrations/, https://ellislab.com/codeigniter/user-guide/libraries/migration.html

Wednesday, April 1, 2015

How To Set Base URL To HTTPS in CodeIgniter?

If you need the secure base url i.e. HTTPS URL, you can create helper file to manage it.
We will create secure version of base url function. For this we will create a helper file 'MY_url_helper.php' and save it in 'system/application/helpers'.
Then, open the MY_url_helper.php file (system/application/helpers/MY_url_helper.php) and add the following codes.


<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');


if (! function_exists('secure_base_url'))
{
    function secure_base_url()
    {
        if ($_SERVER["SERVER_PORT"] != 443)
        {
            return str_replace("http://", "https://" , base_url());
        }
    }
}


/* End of file MY_url_helper.php */
/* Location: ./application/helpers/MY_url_helper.php */


You can load the helper and print the secure base url as follows:
$this->load->helper('my_url_helper');
echo secure_base_url();

//output : https://localhost:8888/myProject

Now we have secured versions of base url function. You may now use it when you need https secure base url.

Wednesday, March 25, 2015

How To Search Key In Array And Return Its Value Using PHP?

You can get corresponding value associated with array key by using simple function as below.
function get_value_by_key($array,$key)
{
 foreach($array as $k => $each)
 {
   if($k == $key)
   {
     return $each;
   }
  
   if(is_array($each))
   {
     if($return = get_value_by_key($each,$key))
     {
       return $return;
     }
   }
  
  }
 
}

//creating array
$array = array
(
    '124' => 'Morning',
    '134' => 'Evening',
    '135' => 'Night'    
);

echo get_value_by_key($array,'124'); // outputs: Morning
echo get_value_by_key($array,'135'); // outputs: Night


This function loops through all the keys of an array and return the value associated with assigned variable $key.
Ref: http://stackoverflow.com/a/4467135

Tuesday, March 24, 2015

How To Send JSON Via POST In Cross Domain Using Codeigniter or PHP?

Sometimes, you'll come across web services and APIs that will require you to send JSON via a POST request.
CodeIgniter-cURL is a CodeIgniter library which makes it easy to do simple cURL requests and makes more complicated cURL requests easier too.

Sending JSON Via POST In Codeigniter

The Code:
//load the Curl library
$this->load->library('Curl');

$url = 'http://example.com/';

//The JSON data.
$jsonData = array(
    'username' => 'MyUsername',
    'password' => 'MyPassword'
);

//Encode the array into JSON.
$jsonDataEncoded = json_encode($jsonData);

// Start session (also wipes existing/previous sessions)
$this->curl->create($url);

// Option			
$this->curl->option(CURLOPT_HTTPHEADER, array('Content-type: application/json; Charset=UTF-8'));

// Post - If you do not use post, it will just run a GET request			
$this->curl->post($jsonDataEncoded);
		
// Execute - returns responce 
echo $result = $this->curl->execute();	

Step by step explanation of the above code:
1. Install the Curl Library from CodeIgniter-cURL and placed it inside 'application/libraries' - application/libraries/Curl.php
2. Load the Curl Library
3. We setup the URL that we want to send our JSON to.
4. We setup a PHP array containing sample data.
5. We encoded our PHP array into a JSON string by using the function json_encode.
6. We started cURL session using $this->curl->create.
7. We set the content-type of our request to application/json. It is extremely important to note that you should always use "application/json", not "text/json". Simply put, using "text/json" is incorrect!
8. We specified that we were sending a POST request and attached our JSON data using $this->curl->post
9. Finally, we used the function $this->curl->execute to execute our POST request.

As you can see, it's not much different than sending a regular POST request. In fact, it's actually pretty simple.

Sending JSON Via POST In PHP

The code:
//API Url
$url = 'http://example.com/api/JSON/create';
 
//Initiate cURL.
$ch = curl_init($url);
 
//The JSON data.
$jsonData = array(
    'username' => 'MyUsername',
    'password' => 'MyPassword'
);
 
//Encode the array into JSON.
$jsonDataEncoded = json_encode($jsonData);
 
//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);
 
//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
 
//Set the content type to application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); 
 
//Execute the request
$result = curl_exec($ch);
Step by step explanation of the above code:
1. We setup the URL that we want to send our JSON to. 2. We initiated cURL using curl_init. 3. We setup a PHP array containing sample data. 4. We encoded our PHP array into a JSON string by using the function json_encode. 5. We specified that we were sending a POST request by setting the CURLOPT_POST option to 1. 6. We attached our JSON data using the CURLOPT_POSTFIELDS option. 7. We set the content-type of our request to application/json. It is extremely important to note that you should always use "application/json", not "text/json". Simply put, using "text/json" is incorrect! 8. Finally, we used the function curl_exec to execute our POST request.

Source: http://thisinterestsme.com/sending-json-via-post-php/

Thursday, February 19, 2015

How To Fix Multiple Attachments Problem in PHPMailer?

Before sending email with multiple attachments, you need to fix some bugs in the PHPMailer library. You can download the PHPMailer library from https://github.com/PHPMailer/PHPMailer

To be able to send multiple attachments in email via PHPMailer, following patch has to be applied to 'class.phpmailer.php' (methods "AddAttachment" and "AddStringAttachment"))
ORIGINAL CODE:
$this->attachment[] = array(
0 => $path,
1 => $filename,
2 => $name,
3 => $encoding,
4 => $type,
5 => false, // isStringAttachment
6 => 'attachment',
7 => 0
);

PATCHED CODE:
$this->attachment[] = array(
0 => $path,
1 => $filename,
2 => $name,
3 => $encoding,
4 => $type,
5 => false, // isStringAttachment
6 => 'attachment',
7 => uniqid()
);


The problem is caused by the cid-uniqueness check in AttachAll(), in combination with attachment[7] being set to 0 in AddAttachment and AddStringAttachment.

Now after patching the library, to send multiple attachments is very easy in PHPMailer. You need to simply add a following piece of codes and you are ready to send email with multiple attachments.
$mail->addAttachment('/tmp/image1.jpg', '1.jpg');    // Attachment 1
$mail->addAttachment('/tmp/image2.jpg', '2.jpg');    // Attachment 2

Ref: https://code.google.com/a/apache-extras.org/p/phpmailer/issues/detail?id=151

Monday, February 9, 2015

How to Install & Enable Curl on Ubuntu LAMP Stack?

You only have to install the php5-curl library.
Alternative 1
You can do this by running
sudo apt-get install php5-curl
You will need to restart the server afterwards:
sudo service apache2 restart

Alternative 2
sudo apt-get update
sudo apt-get install php5

sudo apt-get install libapache2-mod-php5

sudo apt-get install curl libcurl3 libcurl3-dev php5-curl
and then:
cd /etc/php5/apache2/

sudo nano php.ini
and add this command: extension=curl.so
the last thing restart apache.

Source: http://askubuntu.com/questions/9293/how-do-i-install-curl-in-php5

Thursday, February 5, 2015

How To Solve Disallowed Key Characters Error In Codeigniter?

I was trying to implement jQuery AJAX form data serialize using Codeigniter and getting error "Disallowed Key Characters". This error bugged me for hours.

I opened the system/codeigniter/system/core/input.php file:
Find the function _clean_input_keys($str)

Change:

exit('Disallowed Key Characters.');

to:

  exit('Disallowed Key Characters.'. $str);

It will tell you what characters are causing this error or problem. The problem was naming of the input field. I named input field as

<input type="text" name="myarray['data1']" \>

And I just changed the input's name.

<input type="text" name="myarray[data1]" \>


And it worked. :)

Tuesday, January 27, 2015

How Fo Fix .htaccess Problem In Codeigniter on Ubuntu 14.04 LAMP Stack Server?

All was working nicely in the localhost. But when I transfered the project on the Ubuntu 14.04 LAMP Stack Server, I was unable to access the .htaccess file in my projects root. Whenever I try to serve a page, I get a 404 error. After some research I found out the solution to fix it.

/* Preliminary steps to make sure the correct config in CI */

1. Make .htaccess file in your CI root directory using below code

   RewriteEngine on
   RewriteCond $1 !^(index\.php|assets|robots\.txt)
   RewriteRule ^(.*)$ index.php?/$1 [L]

2. Check /application/config/config.php and set $config['index_page'] = "";

3. make sure that mod_rewrite is on your server. Use phpinfo(), if you are not sure.


After enabling mod_rewrite, we need to change setting of AllowOverride to All
/* Change the apache2 configuration to enable override all */

1. Find your apache2.conf, in my case, it's in /etc/apache2/

2. So open it and change the expected feature:

   Find and change on <directory  /var/www/>
     AllowOverride none
     to
     AllowOverride All

3. Restart your apache to make sure new changes is activated. I did via terminal as below.

     root@example.se:~# service apache2 restart 

And it's working. :)

Using SSH To Import MySQL Database via Terminal

The file must be in .sql format. It can not be compressed in a .zip or .tar.gz file.
1. Upload the SQL file to the server eg. file_import.sql.
2. If the database does not exist please create one with an user. Note the username and password.
3. Log into the server through SSH
4. Type this this command: mysql -pPassword database_name < file_import.sql

I have wrote detail steps about how I successfully imported the mysql database using SSH via terminal. I have tested in Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu).
/* Terminal example*/

Anup-2:~ anup$ ssh root@example.se  //initializing SSH connection 
root@example.se.se's password:****** //Enter password to log in to server
root@example.se:~# mysql -u root -p //Command to login to mysql server 
Enter password: *****  //Enter password to log in to mysql server

/* ... You will get welcome message 
.......... Last login: Mon Jan 26 15:27:35 2015 from ..... */

mysql> show databases; // to list all the databases
mysql> exit;  //exit to root server
Bye
root@example.se:#  cd /

root@example.se:/# ls // list all the files inside root directory 

root@dmsstage:/# mysql -pPassword database_name < file_import.sql  //command to import your mysql database (Place the password immediately after -p)

root@dmsstage:/# mysql -pPassword // login to mysql to verify if the database has been imported
mysql> use database_name; //command to select database;
Database changed
mysql> show tables; //command to list all the tables inside the database

Monday, January 19, 2015

How To Clone a Row in MySQL Using Codeigniter?

If you've ever needed to clone or duplicate a MySQL row or record with a unique ID field, here is a clean and simple Codeigniter function. It clones the field names and the row values and then insert datas into table with unique primary key.
function DuplicateMySQLRecord ($table, $primary_key_field, $primary_key_val) 
{
   /* generate the select query */
   $this->db->where($primary_key_field, $primary_key_val); 
   $query = $this->db->get($table);
  
    foreach ($query->result() as $row){   
       foreach($row as $key=>$val){        
          if($key != $primary_key_field){ 
          /* $this->db->set can be used instead of passing a data array directly to the insert or update functions */
          $this->db->set($key, $val);               
          }//endif              
       }//endforeach
    }//endforeach

    /* insert the new record into table*/
    return $this->db->insert($table); 
}