Friday, September 25, 2015

Download PDF file via jQuery Ajax

Download PDF file via jQuery Ajax

Solution 1:

downloadURL(data.printPDFURL, basename(data.printPDFURL));

function basename(path) {
  return path.split(/[\\/]/).pop();
}

function downloadURL(url, name) {
  var link = document.createElement('a');
  link.download = name;
  link.href = url;
  link.click();
}

Solution 2:

window.open(data.printPDFURL, '_blank');

Solution 3:

window.location = data.printPDFURL;

Solution 4:

$('<iframe>').attr('src', downloadThing.attr('href')).appendTo('body').load(function() {
   $(this).remove();
});

Reference:

http://stackoverflow.com/questions/3820381/need-a-basename-function-in-javascript
http://stackoverflow.com/questions/3749231/download-file-using-javascript-jquery
http://pixelscommander.com/en/javascript/javascript-file-download-ignore-content-type/

Thursday, September 24, 2015

Install Apache 2.4, PHP 5.6, and MySQL 5.6 on FreeBSD 10

# pkg info | egrep -i 'apache|php|mysql'

apache24-2.4.10_2
php56-5.6.3
mysql56-server-5.6.22

Quick Notes:

  • To have Apache talks to PHP-FPM, you no longer need to install mod_fastcgi or mod_fcgid because it's built-in since Apache 2.4. The official module to use is mod_proxy_fcgi instead of the ancient mod_fastcgi and mod_fcgid (were third party modules).
  • Since Apache 2.4.9, the built-in mod_proxy_fcgi module now supports network sockets (Unix socket support for mod_proxy_fcgi).
  • Since PHP 5.5, you no longer need to install APC (Alternative PHP Cache) because Zend Optimizer+ is directly built in.
  • PHP 5.6 is shipped with the phpdbg interactive debugger.
  • Since MySQL 5.6.8, it won't ship those MySQL configuration tempalte files because this release continues the process begun in MySQL 5.6.6 of making changes to the default values of server parameters. The motivation for these changes is to provide better out-of-box performance and to reduce the need for database administrators to change settings manually. These changes are subject to revision in future releases as we gain feedback.
  • PHP Fights HHVM and Zephir with PHPNG

# pw useradd -n git -s /bin/tcsh -w yes -c "a description" -m

# vim /usr/local/etc/php-fpm.conf

listen = 127.0.0.1:9000
;listen = /tmp/php-fpm.sock

listen.owner = www
listen.group = www
listen.mode = 0660

# vim /usr/local/etc/apache24/httpd.conf

LoadModule proxy_module libexec/apache24/mod_proxy.so
LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so

LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so
#LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so

LoadModule rewrite_module libexec/apache24/mod_rewrite.so

LoadModule ssl_module libexec/apache24/mod_ssl.so

ServerName bsd-dev.local:80

DocumentRoot "/home/srv/apache2.4"

<Directory "/home/srv/apache2.4">
  AllowOverride All
</Directory>

Include etc/apache24/extra/httpd-ssl.conf
Include etc/apache24/extra/httpd-vhosts.conf

# vim /usr/local/etc/apache24/extra/httpd-vhosts.conf

<VirtualHost *:80>
    ServerAdmin webmaster@dummy-host.example.com
    DocumentRoot "/home/srv/apache2.4/drupal8"
    ServerName drupal8.bsd-dev.local
    #ServerAlias www.dummy-host.example.com
    ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/tmp/php-fpm.sock|fcgi://127.0.0.1:9000/home/srv/apache2.4/drupal8/
    DirectoryIndex index.php index.html index.htm
    ErrorLog "/var/log/drupal8-bsd-dev.local-error_log"
    CustomLog "/var/log/drupal8-bsd-dev.local-access_log" common
</VirtualHost>

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile "/usr/local/etc/apache22/ssl/mydomain.com/1b20ec56bae90f.crt"
    SSLCertificateKeyFile "/usr/local/etc/apache22/ssl/mydomain.com/mydomain.com.key"
    SSLCertificateChainFile "/usr/local/etc/apache22/ssl/mydomain.com/gd_bundle-g1-g1.crt"

    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/home/srv/web-dev/apache22/host_not_found/$1

    ServerAdmin webmaster@dummy-host2.example.com
    DocumentRoot "/home/srv/web-dev/apache22/host_not_found"
    ErrorLog "/var/log/apache22/host-not-found-error_log"
    CustomLog "/var/log/apache22/host-not-found-access_log" common
</VirtualHost>

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile "/usr/local/etc/apache22/ssl/mydomain.com/1b20ec56bae90f.crt"
    SSLCertificateKeyFile "/usr/local/etc/apache22/ssl/mydomain.com/mydomain.com.key"
    SSLCertificateChainFile "/usr/local/etc/apache22/ssl/mydomain.com/gd_bundle-g1-g1.crt"

    ServerAdmin webmaster@dummy-host.example.com
    DocumentRoot "/home/srv/web-dev/apache22/drupal6"

    ServerName web-dev.local
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/home/srv/web-dev/apache22/drupal6/$1

    DirectoryIndex /index.php index.php index.html index.htm

    ErrorLog "/var/log/apache22/host-not-found-error_log"
    CustomLog "/var/log/apache22/host-not-found-access_log" common
</VirtualHost>

# /usr/local/etc/rc.d/apache24 restart

# httpd -t -D DUMP_VHOSTS

VirtualHost configuration:
*:80                   is a NameVirtualHost
         default server web-dev.local (/usr/local/etc/apache24/extra/httpd-vhosts.conf:23)
         port 80 namevhost web-dev.local (/usr/local/etc/apache24/extra/httpd-vhosts.conf:23)

*:443                  is a NameVirtualHost
         default server web-dev.local (/usr/local/etc/apache24/extra/httpd-vhosts.conf:82)
         port 443 namevhost web-dev.local (/usr/local/etc/apache24/extra/httpd-vhosts.conf:82)

# vim /etc/hosts

127.0.0.1 bsd-dev.local
127.0.0.1 drupal8.bsd-dev.local

# /usr/local/etc/rc.d/apache24 restart

# httpd -V | grep MPM

Server MPM:     event

Check the PHP-FPM setting:

<?php
  echo phpinfo();
?>

Note: you should see the message: Server API: FPM/FastCGI

# cp /usr/local/share/mysql/my-default.cnf /etc/my.cnf

# vim /etc/rc.conf

mysql_enable="YES"
mysql_dbdir="/home/srv/mysql56"

# vim /etc/my.cnf

[mysqld]
innodb_buffer_pool_size = 512M
datadir = /home/srv/mysql56

# /usr/local/bin/mysql_install_db

Check if this file exists (remove it maybe?):

# ls /usr/local/my.cnf

# find /home/srv/mysql56/ | xargs -I {} chown mysql:mysql {}
# find /home/srv/mysql56/ -type d | xargs -I {} chmod 700 {}
# find /home/srv/mysql56/ -type f | xargs -I {} chmod 660 {}

# /usr/local/etc/rc.d/mysql-server restart

# /usr/local/bin/mysql_secure_installation

# mysql -u root -p

mysql> GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' IDENTIFIED BY '123456';
mysql> FLUSH PRIVILEGES;

# rm ~/.mysql_history

# cd
# touch ~/.my.cnf
# chmod 400 ~/.my.cnf
# vim ~/.my.cnf

[client]
host = localhost
port = 3306
user = root
password = MyPassword

[clientconn1]
host = localhost
port = 3306
user = root
password = MyPassword
database = MyDBName

[mysqldump]
host = localhost
port = 3306
user = root
password = MyPassword

Reference:

https://wiki.apache.org/httpd/PHP-FPM
http://blog.ijun.org/2012/01/mysqldump-read-password-from-file-for.html

Wednesday, September 23, 2015

PDF tools

PDF tools

// Good
Setasign is the first company to offer commercial PDF components written in the interpreted PHP language.
http://www.setasign.com/

// Good
PDFtk
https://www.pdflabs.com/tools/pdftk-server/

// Good
tcPDF
http://www.tcpdf.org/index.php

// Good
wkhtmltopdf
http://code.google.com/p/wkhtmltopdf/

pdftailor
https://github.com/documentcloud/pdftailor

Zend Framework's Zend_Pdf
http://framework.zend.com/manual/en/zend.pdf.html

PhantomJS
http://phantomjs.org/

PDF.js
http://mozilla.github.io/pdf.js/

Use Imagemagick to combine merge multiple PDF files into one single file

Use Imagemagick to combine merge multiple PDF files into one single file

Install ImageMagick:

# yum install gcc php-devel php-pear
# yum install ImageMagick ImageMagick-devel

Install ImageMagick PHP Extension:

# pecl install imagick

Merging multiple PDF files into one file:

# convert -density 150 *.pdf output.pdf

Troubleshoot:

convert.exe: FailedToExecuteCommand `"gswin32c.exe" -q -dQUIET -dSAFER -dBATCH -
dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEV
ICE=pamcmyk32" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" -dUseCIEColor
"-sOutputFile=C:/Users/MDOLAN~1.COR/AppData/Local/Temp/magick-3704HYGOqqIK5rhI%d
" "-fC:/Users/MDOLAN~1.COR/AppData/Local/Temp/magick-3704vK6aHo7Ju9WO" "-fC:/Use
rs/MDOLAN~1.COR/AppData/Local/Temp/magick-3704GQSF9kK8WAw6"' (The system cannot
find the file specified.
) @ error/delegate.c/ExternalDelegateCommand/480.
convert.exe: PDFDelegateFailed `The system cannot find the file specified.
' @ error/pdf.c/ReadPDFImage/797.
convert.exe: no images defined `a.jpg' @ error/convert.c/ConvertImageCommand/323
0.

You need to install Ghostscript in order to rasterize vector files (PDF, EPS, PS, etc.) with ImageMagick. IM will shell out to Ghostscript when doing these manipulations (you can see it if you use the -verbose tag in your IM invocation). You could also use Ghostscript by itself to rasterize vector files.

Reference:

http://www.imagemagick.org/script/index.php
http://tecadmin.net/install-imagemagick-on-linux/
http://stackoverflow.com/questions/32466112/imagemagick-convert-pdf-to-jpeg

pkg search returns nothing on FreeBSD 10

pkg search returns nothing on FreeBSD 10

Try forcing an update of the remote repository catalog:

# pkg update -f

# pkg search imagemagick

ImageMagick-6.9.2.0,1
ImageMagick-nox11-6.9.2.0,1
ImageMagick7-7.0.0.0.b20150902
ImageMagick7-nox11-7.0.0.0.b20150902
fpc-imagemagick-2.6.4_5

PDFtk Server

PDFtk Server can:

Merge PDF Documents or Collate PDF Page Scans
Split PDF Pages into a New Document
Rotate PDF Documents or Pages
Decrypt Input as Necessary (Password Required)
Encrypt Output as Desired
Fill PDF Forms with X/FDF Data and/or Flatten Forms
Generate FDF Data Stencils from PDF Forms
Apply a Background Watermark or a Foreground Stamp
Report PDF Metrics, Bookmarks and Metadata
Add/Update PDF Bookmarks or Metadata
Attach Files to PDF Pages or the PDF Document
Unpack PDF Attachments
Burst a PDF Document into Single Pages
Uncompress and Re-Compress Page Streams
Repair Corrupted PDF (Where Possible)
PDFtk Server does not require Adobe Acrobat or Reader, and it runs on Windows, Mac OS X and Linux.

Reference:

https://www.pdflabs.com/tools/pdftk-server/

Thursday, September 17, 2015

Use CSS "text-overflow" to truncate long string texts

Use CSS "text-overflow" to truncate long string texts

When using Rails to truncate strings, you may end up with strings that are still too long for their container or are not as long as they could be. You can get a prettier result using stylesheets.

The CSS property text-overflow: ellipsis has been around for quite a long time now but since Firefox did not support it for ages, you did not use it. Since Firefox 7 you can!

Consider this HTML and Sass for a box that is not wide enough for its content:

<div id="greetings">
  Hello universe!
</div>

#greetings {
  width: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis; /* This is where the magic happens */
}

While incompatible browsers (IE 5.5, Firefox up until 6) will just cut off the text when it reaches its container's borders, in most browsers you will see something like:

Hello univ…

Nice, eh?

When you are doing this for a mobile application, also use -o-text-overflow to target Opera Mobile and Opera Mini which still use the prefixed version.

Reference:

http://makandracards.com/makandra/5883-use-css-text-overflow-to-truncate-long-texts

Saturday, September 12, 2015

send mail useful arguments

<?php
$mail_dataArr = array(
  'sender_name' => 'My Name',
  'sender_mail' => 'me@example.com',
  'title' => 'My subject',
  'body' => 'My body',
);

test_sendmail('test@example.com', $mail_dataArr);

function test_sendmail($receiver_mail, $mail_dataArr) {
  $FROM = $mail_dataArr['sender_name'] . '<' . $mail_dataArr['sender_mail'] . '>';

  $headers = '';
  $headers .= 'MIME-Version: 1.0' . "\r\n";
  $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
  $headers .= 'From: ' . $FROM . "\r\n";
  //$headers .= !empty($REPLY_TO) ? 'Reply-To: ' . $REPLY_TO . "\r\n" : '';
  //$headers .= 'Bcc: ' . $BCC_LIST . PHP_EOL;
  $headers .= 'X-Mailer: PHP/' . phpversion() . PHP_EOL;

  mail($receiver_mail, $mail_dataArr['title'], $mail_dataArr['body'], $headers, "-odb -f " . $mail_dataArr['sender_mail']);
}
?>

Friday, September 11, 2015

Is there a better way to do optional function parameters in Javascript?

Is there a better way to do optional function parameters in Javascript?

use a default value if the parameter is omitted:

if (typeof optionalArg === 'undefined') {
  optionalArg = 'default';
}

Reference:

http://stackoverflow.com/questions/148901/is-there-a-better-way-to-do-optional-function-parameters-in-javascript

Thursday, September 10, 2015

What is the cleanest way to get the progress of JQuery ajax request?

Something like this for $.ajax (HTML5 only though):

$.ajax({
        type: 'POST',
        url: "/",
        data: {},
        dataType: 'json',
        xhr: function() {
            $('#formLoadingDiv').show();

            var xhr = new window.XMLHttpRequest();

            xhr.upload.addEventListener("progress", function(evt) {
                if (evt.lengthComputable) {
                    var percentComplete = evt.loaded / evt.total;
                    //Do something with upload progress here
                }
            }, false);

            xhr.addEventListener("progress", function(evt) {
                if (evt.lengthComputable) {
                    var percentComplete = evt.loaded / evt.total;
                    //Do something with download progress
                }
            }, false);

            return xhr;
        },
    })
    .done(function(data) {
        if (data.status === true) {} else if ('errors' in data) {
            console.log(data);
        }
    })
    .fail(function() {
        console.log('failed');
    })
    .always(function() {
        $('#formLoadingDiv').hide();
    });

Reference:

http://stackoverflow.com/questions/19126994/what-is-the-cleanest-way-to-get-the-progress-of-jquery-ajax-request

select checked input checkbox by jQuery selector

            $("input[name='sendMethod[]']:checked").each(function(){
              console.log($(this).val());
              $(this).prop('checked', false);
            });

Wednesday, September 9, 2015

Add some attributes or set options data to the existing field of an entity

Add some attributes or set options data to the existing field of an entity:

# vim src/My/DemoBundle/Form/Type/ContactType.php

<?php
namespace My\DemoBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

class ContactType extends AbstractType
{
    private $idJobFieldOptArr;


    public function __construct($optArr)
    {
        $this->idJobFieldOptArr = $optArr['idJobFieldOptArr'];
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('firstname', 'text', array(
          'required' => FALSE,
        ));
        $builder->add('lastname', 'text', array(
          'required' => FALSE,
        ));
        $builder->add('idjobfield', 'choice', array(
          'required' => FALSE,
          'choices' => $this->idJobFieldOptArr,
          'placeholder' => '--- select ---',
        ));

        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $entity = $event->getData();
            $form = $event->getForm();

            if ($entity !== NULL && $entity->getId()) {
              $_id = $entity->getId();

              $firstnameOrig = $form->get('firstname')->getConfig()->getOptions();
              $firstnameOrig['attr'] = array('data-test' => 'test ' . $_id);

              $form->add('firstname', 'text', $firstnameOrig);
            }
        });
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'My\DemoBundle\Entity\Contact',
            #'idJobFieldOptArr' => null,
        ));
    }
}
?>

# vim src/My/DemoBundle/Controller/ContactController.php

<?php
namespace My\DemoBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use My\DemoBundle\Entity\User;
use My\DemoBundle\Entity\Contact;

use My\DemoBundle\Form\Type\ContactType;

class ContactController extends Controller
{
    public function addAction(Request $request)
    {
        $idJobFieldOptArr = array(
          1 => 'Sales',
          2 => 'Accounting',
          3 => 'Management',
        );

        $user = self::myFindByEmail($email);

        if (!$user) {
          $user = new User();
        }

        $user->addContact(new Contact());

        $formName = 'contactsform';

        $formDefault = array(
            'email' => 'test@example.com',
            'contacts' => $user->getContacts(),
        );
        $formAttr = array('attr' => array(
          'class' => $formName,
        ));

        $form = $this->get('form.factory')->createNamedBuilder($formName, 'form', $formDefault, $formAttr)
          ->add('email', 'email', array(
            'label' => 'Email',
          ))
          ->add('contacts', 'collection', array(
            'type' => new ContactType(['idJobFieldOptArr' => $idJobFieldOptArr]),
            'allow_add' => TRUE,
            'allow_delete' => TRUE,
            #'options'  => array(
            #  #'idJobFieldOptArr' => $idJobFieldOptArr,
            #),
          ))
          ->add('save', 'submit', array('label' => 'Save'))
          ->getForm();
    }

    private function myFindByEmail($email)
    {
      return $this->getDoctrine()
               ->getRepository('MyDemoBundle:User')
               ->findOneByEmail($email);
    }

}
?>

Redirect to the current page

Redirect to the current page:

return $this->redirect($request->getUri());

Saturday, September 5, 2015

Change owner or group of a symbolic link

To change the owner of a symbolic link _only_ you can use chown with the -h switch:
# chown -h user:group symboliclink

Note: without the -h parameter, it will change the owner of the _target_ the symbolic link points to.

Install vsftpd FTP server on CentOS 7

# yum install vsftpd

# vim /etc/vsftpd/vsftpd.conf

anonymous_enable=NO

local_enable=YES

chroot_local_user=YES

### add these lines to the end of vsftpd.conf. This is to configure to use passive mode. Otherwise, you would see "Failed to retrieve directory listing. Connection timeout".
pasv_enable=YES
pasv_min_port=12000
pasv_max_port=12100
pasv_address=<Public IP of your instance>
pasv_addr_resolve=NO

# systemctl enable vsftpd
# systemctl restart vsftpd

# useradd ftp-user1 -m -c 'ftp user' -s /sbin/nologin

# usermod -s /sbin/nologin ftp-user1

# chmod a-w /home/ftp-user1

Note: if you see 500 OOPS: vsftpd: refusing to run with writable root inside chroot (), make sure the user's home directory is not writable.

# passwd ftp-user1

# firewall-cmd --permanent --zone=public --add-port=20-21/tcp
# firewall-cmd --permanent --zone=public --add-port=12000-12100/tcp
# firewall-cmd --reload
# firewall-cmd --zone=public --list-all

Note: make sure you do open these ports on your Amazon EC2 instance security group as well.

# setsebool -P ftp_home_dir 1
# getsebool -a | grep ftp

ftp_home_dir --> on

Reference:

http://stackoverflow.com/questions/4723023/vsftpd-error-listing-directories
http://linuxconfig.org/how-to-setup-vsftpd-ftp-file-server-on-redhat-7-linux

Basic Concepts in Firewalld

Introduction


Firewalld is a complete firewall solution available by default on CentOS 7 servers. In this guide, we will cover how to set up a firewall for your server and show you the basics of managing the firewall with the firewall-cmd administrative tool (if you'd rather use iptables with CentOS, follow this guide).

Basic Concepts in Firewalld

Before we begin talking about how to actually use the firewall-cmd utility to manage your firewall configuration, we should get familiar with a few basic concepts that the tool introduces.

Zones


The firewalld daemon manages groups of rules using entities called "zones". Zones are basically sets of rules dictating what traffic should be allowed depending on the level of trust you have in the networks your computer is connected to. Network interfaces are assigned a zone to dictate the behavior that the firewall should allow.

For computers that might move between networks frequently (like laptops), this kind of flexibility provides a good method of changing your rules depending on your environment. You may have strict rules in place prohibiting most traffic when operating on a public WiFi network, while allowing more relaxed restrictions when connected to your home network. For a server, these zones are not as immediately important because the network environment rarely, if ever, changes.

Regardless of how dymaic your network environment may be, it is still useful to be familiar with the general idea behind each of the pre-defined zones for firewalld. In order from least trusted to most trusted, the pre-defined zones within firewalld are:

drop: The lowest level of trust. All incoming connections are dropped without reply and only outgoing connections are possible.

block: Similar to the above, but instead of simply dropping connections, incoming requests are rejected with an icmp-host-prohibited or icmp6-adm-prohibited message.

public: Represents public, untrusted networks. You don't trust other computers but may allow selected incoming connections on a case-by-case basis.

external: External networks in the event that you are using the firewall as your gateway. It is configured for NAT masquerading so that your internal network remains private but reachable.

internal: The other side of the external zone, used for the internal portion of a gateway. The computers are fairly trustworthy and some additional services are available.

dmz: Used for computers located in a DMZ (isolated computers that will not have access to the rest of your network). Only certain incoming connections are allowed.

work: Used for work machines. Trust most of the computers in the network. A few more services might be allowed.

home: A home environment. It generally implies that you trust most of the other computers and that a few more services will be accepted.

trusted: Trust all of the machines in the network. The most open of the available options and should be used sparingly.

To use the firewall, we can create rules and alter the properties of our zones and then assign our network interfaces to whichever zones are most appropriate.

Reference:

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-firewalld-on-centos-7

Friday, September 4, 2015

Simple PHP encryption and decryption

<?php
/**
 * simple method to encrypt or decrypt a plain text string
 * initialization vector(IV) has to be the same when encrypting and decrypting
 * PHP 5.4.9
 *
 * this is a beginners template for simple encryption decryption
 * before using this in production environments, please read about encryption
 *
 * @param string $action: can be 'encrypt' or 'decrypt'
 * @param string $string: string to encrypt or decrypt
 *
 * @return string
 */
function encrypt_decrypt($action, $string) {
    $output = NULL;

    $encrypt_method = "AES-256-CBC";
    $secret_key = 'This is my secret key';
    $secret_iv = 'This is my secret iv';

    // hash
    $key = hash('sha256', $secret_key);

    // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
    $iv = substr(hash('sha256', $secret_iv), 0, 16);

    if( $action == 'encrypt' ) {
        $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
    }
    else if( $action == 'decrypt' ){
        $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
    }

    return $output;
}

$plain_txt = "This is my plain text";
echo "Plain Text = $plain_txt\n";

$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = $encrypted_txt\n";

$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text = $decrypted_txt\n";

if( $plain_txt === $decrypted_txt ) {
  echo "SUCCESS";
}
else {
  echo "FAILED";
}

echo "\n";
?>

Reference:

https://naveensnayak.wordpress.com/2013/03/12/simple-php-encrypt-and-decrypt/

The server returned a "404 Not Found"

Oops! An Error Occurred
The server returned a "404 Not Found".
Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused. 

Make sure you have the root / path in your routing.yml:

# vim app/config/routing.yml

my_demo_home:
    path:     /
    defaults: { _controller: MyDemoBundle:Default:home }

Clear the cache:

# php app/console cache:clear --env=prod

Clearing the cache for the prod environment with debug false

Check the routing:

# php app/console debug:router --env=prod

[router] Current routes
 Name                  Method Scheme Host Path
 my_home              ANY    ANY    ANY  /
 my_demo_hello        ANY    ANY    ANY  /demo/hello/{name}
 my_demo_home         ANY    ANY    ANY  /demo/
 homepage              ANY    ANY    ANY  /

How to detect if a jQuery selector returns null?

if ( $("#test").length ) {
  alert("element(s) found")
} 
else {
  alert("nothing found")
}

Thursday, September 3, 2015

How to theme the individual fields for collection type of a form

Solution 1 - override the collection_widget theme:

Let's say we have a form looks like this:

<?php
$entity = 'MyDemoBundle:User';
$id = 5;

$user = $this->getDoctrine()->getRepository($entity)->find($id);

$formName = 'contactsform';

$formDefault = array(
  'username' => $user->getUsername(),
  'contacts' => $user->getContacts(),
);

$formAttr = array('attr' => array(
  'class' => $formName,
));

$form = $this->get('form.factory')->createNamedBuilder($formName, 'form', $formDefault, $formAttr)
    ->add('username', 'text')
    ->add('contacts', 'collection', array(
      'type' => new ContactType(),
      'allow_add' => TRUE,
      'allow_delete' => TRUE,
    ))
    ->add('save', 'submit', array('label' => 'Save'))
    ->getForm();
?>

And the ContactType looks like this:

<?php
namespace My\DemoBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ContactType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('firstname', 'text');
        $builder->add('lastname');
        $builder->add('email');
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'My\DemoBundle\Entity\Contact',
        ));
    }

    public function getName()
    {
        return 'contact';
    }
}
?>

You can override the collection_widget theme for a single field by referencing the widget like this:

{# src/My/DemoBundle/Resources/views/Form/cust_field_contacts.html.twig #}

{%- block _contactsform_contacts_widget -%}
  {%- for child in form -%}
    {{- form_widget(child) -}}
  {%- endfor -%}
{%- endblock -%}

{%- block _contactsform_contacts_entry_widget -%}
  <li class="test_row">
    {%- for child in form -%}
      <div style="display: inline-block;">
        {{- form_widget(child) -}}
      </div>
    {%- endfor -%}
  </li>
{%- endblock -%}

Note: change the "contactsform" to your form name.

Note: change the "contacts" to your collection type.

Note: the "dash" between the twig tags are for triming the whitespace. For more information, please visit http://twig.sensiolabs.org/doc/templates.html#whitespace-control

To find the unique block name in order to override the built-in one:

{{ dump(form.contacts.vars.prototype) }}
or

{{ dump(child) }}

Then, look for vars > unique_block_prefix, you will see:

FormView {
  vars: array:27 [
    "unique_block_prefix" => "_contactsform_contacts_entry"
  ]
}

To theme an individual field:

{# src/My/DemoBundle/Resources/views/Form/cust_field_contacts.html.twig #}

{%- block _contactsform_contacts_entry_firstname_widget -%}
  <div class="text_widget cust_firstname">
    {{- block('form_widget_simple') -}}
  </div>
{%- endblock -%}

Note: the magic trick here is the "entry" where twig will do the job for you to apply above changes to each row and for each field you specify

Note: change the "contactsform" to your form name.

Note: change the "contacts" to your collection type.

Then, render the label, any errors, and the HTML form widget for the given "collection" widget:

{# src/My/DemoBundle/Resources/views/Contact/contact.html.twig #}

{% form_theme form 'MyDemoBundle:Form:cust_field_contacts.html.twig' %}

{%- block body -%}

  {{- form_row(form.contacts) -}}

{%- endblock -%}

Reference:
http://stackoverflow.com/questions/11498487/symfony2-applying-theme-to-individual-field-for-collection-type

What does the hyphen mean for a block in Twig like in {% block body -%}?

The -%} means to trim whitespace.

See the Whitespace Control section of the docs.

http://twig.sensiolabs.org/doc/templates.html#whitespace-control

Reference:

http://stackoverflow.com/questions/17298902/what-does-the-hyphen-mean-for-a-block-in-twig-like-in-block-body

Wednesday, September 2, 2015

SVN: List files committed for a revision

# svn log --verbose -r 42

My Toolbox

File Synchronization


Dropbox - Dropbox is a service that keeps your files safe, synced, and easy to share.
https://www.dropbox.com/

Mailer


PHPMailer - Probably the world's most popular code for sending email from PHP
https://github.com/PHPMailer/PHPMailer

SwiftMailer - Swift Mailer integrates into any web app written in PHP 5, offering a flexible and elegant object-oriented approach to sending emails with a multitude of features.
http://swiftmailer.org/

Spreadsheet


SpreadJS - SpreadJS is a JavaScript spreadsheet and grid component that displays and manages data much like Microsoft Excel and includes a forumla engine, sorting, filtering, input controls, data visualiztion widgets, Excel I/O and much more.
http://spread.grapecity.com/Products/SpreadJS/

Handsontable - Handsontable is a data grid component with an Excel-like appearance. Built in JavaScript, it integrates with any data source with peak efficiency. It comes with powerful features like data validation, sorting, grouping, data binding, formula support or column ordering.
http://handsontable.com/