Category Archives: Web

Fix “There is no suitable CSPRNG installed on your system” in Plesk

After updating paragonie/random_compat you may get this error. This is caused because version 2.0 stopped using OpenSSL and now it uses /dev/urandom which may not be readable by your PHP configuration. This is fixed adding /dev/urandom to your open_base configuration in “Websites & Domains -> PHP Settings -> open_basedir”:

plesk-open_basedir-dev-urandom

Ref: http://forum.odin.com/threads/how-to-change-php-open_basedir-in-plesk-10-4-4.259102/
https://forum.owncloud.org/viewtopic.php?t=34286
https://github.com/paragonie/random_compat/issues/99

CentOS “Error: php-mysql conflicts with php-mysqlnd” updating with PHP 7.0

If you get an error about a conflict between php-mysql and php-mysqlnd when updating CentOS packages after installing and activating the PHP 7.0 remi package source like this one:

# yum -y install php-mysql

...

--> Finished Dependency Resolution
Error: Package: php-mysql-5.4.45-7.el6.remi.x86_64 (remi)
           Requires: php-pdo(x86-64) = 5.4.45-7.el6.remi
           Removing: php-pdo-5.3.3-46.el6_7.1.x86_64 (@updates)
               php-pdo(x86-64) = 5.3.3-46.el6_7.1
           Updated By: php-pdo-7.0.5-1.el6.remi.x86_64 (remi-php70)
               php-pdo(x86-64) = 7.0.5-1.el6.remi
           Available: php-pdo-5.3.3-40.el6_6.x86_64 (base)
               php-pdo(x86-64) = 5.3.3-40.el6_6
           Available: php-pdo-5.3.3-46.el6_6.x86_64 (updates)
               php-pdo(x86-64) = 5.3.3-46.el6_6
           Available: php-pdo-5.4.45-5.el6.remi.x86_64 (remi)
               php-pdo(x86-64) = 5.4.45-5.el6.remi
           Available: php-pdo-5.4.45-7.el6.remi.x86_64 (remi)
               php-pdo(x86-64) = 5.4.45-7.el6.remi
           Available: php-pdo-7.0.4-1.el6.remi.x86_64 (remi-php70)
               php-pdo(x86-64) = 7.0.4-1.el6.remi
Error: php-mysql conflicts with php-mysqlnd-7.0.5-1.el6.remi.x86_64
Error: Package: php-mysql-5.4.45-5.el6.remi.x86_64 (remi)
           Requires: php-pdo(x86-64) = 5.4.45-5.el6.remi
           Removing: php-pdo-5.3.3-46.el6_7.1.x86_64 (@updates)
               php-pdo(x86-64) = 5.3.3-46.el6_7.1
           Updated By: php-pdo-7.0.5-1.el6.remi.x86_64 (remi-php70)
               php-pdo(x86-64) = 7.0.5-1.el6.remi
           Available: php-pdo-5.3.3-40.el6_6.x86_64 (base)
               php-pdo(x86-64) = 5.3.3-40.el6_6
           Available: php-pdo-5.3.3-46.el6_6.x86_64 (updates)
               php-pdo(x86-64) = 5.3.3-46.el6_6
           Available: php-pdo-5.4.45-5.el6.remi.x86_64 (remi)
               php-pdo(x86-64) = 5.4.45-5.el6.remi
           Available: php-pdo-5.4.45-7.el6.remi.x86_64 (remi)
               php-pdo(x86-64) = 5.4.45-7.el6.remi
           Available: php-pdo-7.0.4-1.el6.remi.x86_64 (remi-php70)
               php-pdo(x86-64) = 7.0.4-1.el6.remi
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

You can just remove the PHP 5.x version of php-mysql:

# yum remove php-mysql

Update all the packages:

# yum -y update

And finally just install php-mysql again but this time it will be from PHP 7.0:

# yum -y install php-mysql

Exit maintenance mode in WordPress when an update fails

To exit maintenance mode in WordPress when an update fails is as easy as deleting the .maintenance file from the root folder. Fixing the update problem is another history…

wordpress-maintenance-mode

Use HTTPS protocol in WordPress 4.4+ for srcset attribute

I’ve started using “Let’s Encrypt” in multiple sites I manage. Just after installing it for this blog I noticed that all images didn’t load because they were originally linked with HTTP.

mixed-content-loaded-over-https-insecure-script

This was easy to fix with a simple SQL update:

UPDATE wp_posts SET post_content = replace(post_content, 'http://tech.enekochan.com', 'https://tech.enekochan.com');

But I still got the “Mixed Content” error messages. Looking at the generated page source code I found that WordPress 4.4+ adds a responsive image attribute to images img tags: srcset. And the problem was that the links there were using HTTP. Adding this code in functions.php solved the issue:

/*
 * Force URLs in srcset attributes into HTTPS scheme.
 * This is particularly useful when you're running a Flexible SSL frontend like Cloudflare
 */
function ssl_srcset( $sources ) {
  foreach ( $sources as &$source ) {
    $source['url'] = set_url_scheme( $source['url'], 'https' );
  }

  return $sources;
}
add_filter( 'wp_calculate_image_srcset', 'ssl_srcset' );

Ref: https://wordpress.org/support/topic/responsive-images-src-url-is-https-srcset-url-is-http-no-images-loaded#post-7767555
https://make.wordpress.org/core/2015/11/10/responsive-images-in-wordpress-4-4/

Multiple class inheritance with Doctrine ODM in Symfony: One collection for multiple document types

When you use Doctrine ORM in Symfony all the data is stored in tables having every row the same columns. Storing different type of entities in the same table is not posible (AFAIK). But MongoDB can store any kind of document in the same collection making possible to have different kind of objects in the same place and thus making inheritance easy to use if you need it.

doctrine-odm-mongodb

In this example I’m going to create the documents needed to reflect an RFID system (from a real application I did sometime ago) where cards, called internally tag, can represent different things: a person, an item, an event, etc. Thus our mongodb database will have a collection of tags with documents of type person, item, event, etc.

Each time a card is used the system will know what it represents using the internal EPC of it: as you may be thinking this will be our ID.

Install MongoDB, the PHP driver and create a new database

This process depends on the operating system you use. Here are the instructions for some of them in older posts:

To create a new database in our mongodb server you have just to make a use statement and create a new collection in it with the mongo client:

> use app
switched to db app
> db.createCollection('tags')
{ "ok" : 1 }

Install MongoDB Doctrine library and DoctrineMongoDBBundle

This process is needed to be able to use MongoDB within the Symfony project. Those steps are extracted from the Symfony DoctrineMongoDBBundle Documentation.

Add the MongoDB Doctrine library and the DoctrineMongoDBBundle to composer.json:

{
    "require": {
        "doctrine/mongodb-odm": "~1.0",
        "doctrine/mongodb-odm-bundle": "~3.0"
    },
}

Now install them using composer. Using a local installation of it:

$ php composer.phar update doctrine/mongodb-odm doctrine/mongodb-odm-bundle

Or a global installation:

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

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

use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
AnnotationDriver::registerAnnotationClasses();

It should look something like this:

<?php
// app/autoload.php
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
use Composer\Autoload\ClassLoader;

/**
 * @var ClassLoader $loader
 */
$loader = require __DIR__.'/../vendor/autoload.php';

AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
AnnotationDriver::registerAnnotationClasses();

return $loader;

Now update AppKernel.php:

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

    // ...
}

Configure MongoDB ODM

Symfony must know how to connect to our mongodb instance. This is configured in app/config/config.yml being the easiest way using the auto_mapping option:

# app/config/config.yml
doctrine_mongodb:
    connections:
        default:
            server: mongodb://localhost:27017
            options: {}
    default_database: test_database
    document_managers:
        default:
            auto_mapping: true

I like using the app/config/parameters.yml to set up the host, port and database name:

# app/config/parameters.yml
parameters:
    mongodb_host: 127.0.0.1
    mongodb_port: 27017
    mongodb_name: app
# app/config/config.yml
imports:
    - { resource: parameters.yml }

doctrine_mongodb:
    connections:
        default:
            server: mongodb://%mongodb_host%:%mongodb_port%
            options: {}
    default_database: %mongodb_name%
    document_managers:
        default:
            auto_mapping: true

The document classes

Now is when we start coding. I’ll suppose you already have an AppBundle created (if not look here at the Symfony Best Practices – Creating the project).

The “parent” class: Single Collection Inheritance

All the different things we want to represent as a document in mongodb in the same collection and an object in PHP must inherit from the same class called tag. The “magic” here is the @MongoDB\InheritanceType("SINGLE_COLLECTION") annotation. This will tell MongoDB ODM that this collection will store different documents and a discrimination field will tell each other apart.

<?php
// src/AppBundle/Document/TagInterface.php

namespace AppBundle\Document;

interface TagInterface
{
}
<?php
// src/AppBundle/Document/Tag.php

namespace AppBundle\Document;

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

/**
 * @MongoDB\Document(collection="tags")
 * @MongoDB\InheritanceType("SINGLE_COLLECTION")
 * @MongoDB\DiscriminatorField("type")
 * @MongoDB\DiscriminatorMap({"person"="Person", "item"="Item"})
 */
class Tag implements TagInterface
{
    /**
     * @MongoDB\Id(strategy="NONE")
     */
    protected $epc;

    /**
     * Set epc
     *
     * @param custom_id $epc
     * @return self
     */
    public function setEpc($epc)
    {
        $this->epc = $epc;
    }

    /**
     * Get epc
     *
     * @return custom_id $epc
     */
    public function getEpc()
    {
        return $this->epc;
    }
}

The inherited classes: extends

Now that we have the parent class the only thing we need to store documents in that collection is extend it:

<?php
// src/AppBundle/Document/Person.php

namespace AppBundle\Document;

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

/**
 * @MongoDB\Document
 */
class Person extends Tag
{
    /**
     * @MongoDB\String
     */
    protected $name;

    /**
     * Set name
     *
     * @param string $name
     * @return self
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string $name
     */
    public function getName()
    {
        return $this->name;
    }
}
<?php
// src/AppBundle/Document/Item.php

namespace AppBundle\Document;

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

/**
 * @MongoDB\Document
 */
class Item extends Tag
{
    /**
     * @MongoDB\Float
     */
    protected $price;

    /**
     * Set price
     *
     * @param float $price
     * @return self
     */
    public function setPrice($price)
    {
        $this->price = $price;

        return $this;
    }

    /**
     * Get price
     *
     * @return float $price
     */
    public function getPrice()
    {
        return $this->price;
    }
}

Store and read documents to/from the collection

All the configuration and classes are done, we can start persisting and finding documents anywhere in the project: a controller, a command, etc. For example lets persist and find some Person and Item objects in a controller:

<?php
// src/AppBundle/Controller/TagsController.php

namespace AppBundle\Controller;

use AppBundle\Document\Item;
use AppBundle\Document\Person;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class TagsController extends Controller
{
    /**
     * @Route("/persist", name="app_persist")
     * @param Request $request The Request object
     * @return Response A Response instance
     */
    public function persistAction()
    {
        $item = new Item();
        $item->setEpc('0000000000000000000000AA');
        $item->setPrice('19.99');

        $person = new Person();
        $item->setEpc('0000000000000000000000AB');
        $item->setName('Eneko');

        $dm = $this->get('doctrine_mongodb')->getManager();
        $dm->persist($item);
        $dm->persist($person);
        $dm->flush();

        return new Response('Created tags');
    }

    /**
     * @Route("/find", name="app_find")
     * @param Request $request The Request object
     * @return Response A Response instance
     */
    public function findAction(Request $request)
    {
        $epc = $request->request->get('epc');
        $tag = $this->get('doctrine_mongodb')
            ->getRepository('AppBundle:Tag')
            ->find($epc);

        if (!$tag) {
            throw $this->createNotFoundException('No tag found for epc '.$epc);
        }

        switch(true) {
            case $tag instanceof Person:
                $type = 'Person';
                break;
            case $tag instanceof Item:
                $type = 'Item';
                break;
        }

        return new Response('Found '.$type);
    }

    /**
     * @Route(
     *     "/find-with-param-converter/{epc}",
     *     requirements={
     *         "epc": "[a-zA-Z0-9]{24}"
     *     },
     *     name="app_find_with_param_converter"
     * )
     * @ParamConverter("tag", class="AppBundle\Document\Tag")
     * @param Request $request The Request object
     * @param TagInterface $tag A object of class Tag or one of its children
     * @return Response A Response instance
     */
    public function findWithParamConverterAction(Request $request, TagInterface $tag)
    {
        switch(true) {
            case $tag instanceof Person:
                $type = 'Person';
                break;
            case $tag instanceof Item:
                $type = 'Item';
                break;
        }

        return new Response('Found '.$type);
    }
}

And how are all those object stored in mongodb and how can Doctrine know what class each one represents? That’s configured in the parent class with the @MongoDB\DiscriminatorField and the @MongoDB\DiscriminatorMap annotations. Each document simply has a field named type with the name of the class on it:

> db.tags.find()
{
    "_id" : "0000000000000000000000AA",
    "type" : "item",
    "price" : 19.99
},
{
    "_id" : "0000000000000000000000AB",
    "type" : "person",
    "name" : "Eneko"
}

Ref: http://doctrine-mongodb-odm.readthedocs.org/en/latest/reference/basic-mapping.html
http://doctrine-mongodb-odm.readthedocs.org/en/latest/reference/inheritance-mapping.html
http://jwage.com/post/30490180105/inheritance-and-mapped-super-classes-in-doctrine