Common files in PHP packages

Jordi Boggiano looks at some common files in PHP packages, using Packagist as a data source.  There are some interesting metrics in there.  For example:

  • 58% of packages include a src/ directory and 5% a lib/ one. That’s surprisingly low to me, that means a lot have the code simply in the root folder.
  • 4% have a bin/ directory, including some sort of CLI executables.
  • 55% have a LICENSE file, that’s.. pretty disastrous but hopefully a lot of those that don’t at least indicate in the README and composer.json
  • 49% have some file or directory indicating the presence of tests (phpunit.xml & co). I am not sure if this is good or bad news to be honest, that depends on your expectations.

Adventure in composer private repositories

First of all, I would like to take this opportunity and wish composer a happy birthday and many more years to come.  It’s been five years, and the world of PHP has changed so drastically that not many people remember how it used to be before.

I would have completely missed the birthday if it wasn’t for all the Google searching I did while working on a weird problem.  But before I get to the problem, let me set the scene.

The big part of composer success is Packagist.org – the repository of almost 100,000 packages (93,572, according to statistics, as of this writing, to be precise), which help one to solve pretty much any problem that PHP can be used for.

As good as the Packagist is, there is often a need for a repository or a package elsewhere.  Whether it’s a commercial library, or sensitive corporate code, having an ability to store it outside of public eye and handle with the same ease and the same tool as the rest of the dependencies is a very welcome feature.

Now we are getting closer to what actually happened.  A while back, I’ve setup deployment and development process for WordPress-based projects.  WordPress doesn’t support composer natively, but there are ways to make it work.  Huge thanks here goes to Roots.

So.  The composer.json file was filled with additional repositories and requirements which told composer where from to fetch things, and where to install them.  Here’s an example:

"repositories": [
    {
        "type": "package",
        "package": {
            "name": "wordpress",
            "type": "webroot",
            "version": "4.4.1",
            "dist": {
                "type": "zip",
                "url": "https://github.com/WordPress/WordPress/archive/4.4.1.zip"
            },
            "require": {
                "fancyguy/webroot-installer": "1.1.0"
            }
        }
    },
    // ...

This got especially useful, when we need to work with commercial plugins, which we couldn’t push to our public repositories, and which we didn’t want to re-distribute with every project.

So far so good. Fast-forward to a few month ago. We are setting up similar development and deployment process, but now for CakePHP-based projects. Things are much easier, since CakePHP 3 natively supports composer for the application itself and for its plugins.

But we still have the need for private repositories here and there, so we follow the same setup as we did for WordPress. This week, we had an unexpected roadblock, which wasn’t making much sense to me. When trying to pull a CakePHP plugin from a private repository, we’d get a nasty exception like this:

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing qobo/cakephp-test-foo (1.0.1)
    Loading from cache


                                                                                                                                              
  [RuntimeException]                                                                                                                          
  Unable to get primary namespace for package qobo/cakephp-test-foo.                                                                          
  Ensure you have added proper 'autoload' section to your plugin's config as stated in README on https://github.com/cakephp/plugin-installer  
                                                                                                                                              

This was confusing. First of all, I’ve never seen this error before. Secondly, I’ve read the README and had the autoloader section in the composer.json as instructed. Thirdly, very similar plugins were working fine.

Long story short, the issue wasn’t related to whether or not the GitHub/BitBucket repository was private or public. It was related to how the repository was configured in the composer.json. Reading and re-reading composer documentation about Repositories finally helped.

You can have a look at our test setup:

CakePHP plugin installer requires the autoload section in composer.json.  But, when the repository is of type “package“, for some reason, the autoload section is ignored altogether.  The RuntimeException “Unable to get primary namespace for package” is thrown by cakephp/plugin-installer (src/Installer/PluginInstaller.php line 274).  The problem is not actually in the cakephp/plugin-installer, but somewhere in the composer.  Maybe it’s intentional or maybe it’s not.  I didn’t have the time to investigate and understand it further.

Switching the repository to type “vcs” fixes the problem.  It also simplifies the composer.json file and removes the need for multiple version definitions, as now composer is using BitBucket/GitHub API to fetch available versions.

Working with encrypted values in SugarCRM 6.5

SugarCRM comes with a variety of modules that store values in the database.  Some of those values are encrypted.  For example, mailbox passwords for inbound and outbound email configurations.

When you create this configurations through the web interface or the API, you don’t need to worry about encryption, as SugarCRM handles that all by itself.  But sometimes, you need to access those values from third-party code.  The easiest way would be of course to use the same API functionality, but this is not always possible (different machines, different technology stack, etc).

It is still possible decrypt the values in the database, if you know where to look.

First of all, here is a little side note for InboundEmail and OutboundEmail modules.  InboundEmail is a full-featured module, which you can find in modules/InboundEmail folder.  OutboundEmail is however not – it lives in include/OutboundEmail .  This might seem surprising, but the reason for this (probably, as I don’t know for sure) is that outbound email configuration is much simpler.  Inbound emails are linked with folders, which are then used to subscribe users, etc.  Outbound emails are just SMTP configurations to use, directly linked to users.

Anyways.  Let’s get back on track.

Most of the encryption and decryption magic happens in include/utils/encryption_utils.php.  If you look through the code, you’ll notice that it deals with mostly two things:

  1. Generating or reading an existing encryption key.
  2. Encrypting or decrypting text with Blowfish, using the encryptionkey.

Encryption keys are stored in custom/blowfish/ folder.  The files that you’ll find there have weird names and a .php extension.  The name of the file comes from the module, for which the key will be used.  ROT13 algorithm is used to convert the name of the module into the file name.  (Note, that for outbound email, the name of the module is OutBoundEmail, not OutboundEmail).

If the encryption key file does not exist, a new one will be generated.  The file will contain a PHP snippet like this:

<?php // created: 2016-04-18 10:00:00 
  $key = array ( 0 => 'a0a0a0a0-b1b1-c3c3-d4d4-e5e5e5e5e5e5',
);

If you accidentally remove the file, then you won’t be able to decrypt any of the values, encrypted with this key, so make sure you backup this up.  Especially considering that this folder might be in your .gitignore, as a sub-folder of custom/ which stored lots of auto-generated stuff.

Note that the file actually defines a $key variable, which, if you will include it in your code, can overwrite your $key variable. So, be warned.

Now, the encryption and decryption is handled with the Crypt_Blowfish library from Pear.  You can find it in include/Pear/Crypt_Blowfish folder.

A little note for the above as well.  The Blowfish.php file which contains the Crypt_Blowfish class, requires the Blowfish/DefaultKey.php file (from the setKey() method).  That requirement uses relative path, but not based on the current file.  Yeah, I know.  So, if you just copy over the library somewhere else, you might need to adjust either path variables, or the setKey() method.

Armed with this knowledge, you can now work with encrypted values stored by the SugarCRM in the database.  Good luck!

Single Sign-On with SugarCRM and RoundCube Using Multiple PHP Sessions

I am currently involved in an interesting integration project at work.  As part of it, we need to create a single sign-on process between SugarCRM (version 6.5.20) and RoundCube (version 1.1.4) webmail application.  RoundCube webmail is being displayed within the iframe inside the SugarCRM user interface, so it would help if users didn’t have to login to RoundCube since they are already authenticated in SugarCRM.

Once the user is authenticated in the SugarCRM, a PHP session is created with, among other information, authenticated user ID.  Using that ID, we can fetch the full user record and get his IMAP credentials, necessary for the RoundCube login.  While this wasn’t too difficult, there were a couple of road bumps that I’d like to document here, so that next time I won’t have to work it all out from scratch again.

Continue reading Single Sign-On with SugarCRM and RoundCube Using Multiple PHP Sessions

APC is dead, long live OPcache

Since this is probably common knowledge by now, this blog post is more a note to my future self.  APC is dead.  Don’t use it.  Use OPcache instead.  APCu is something else.

In the last few years I’ve had so much issues with APC, that I eventually stopped installing it on my servers by default.  Now that I need to squeeze every bit of performance for one of the projects, I looked back at it.  And tried it.  And once again it kicked me in the balls.  Then I remembered that I’ve seen APCu somewhere.  Maybe it’s a newer fork or something.

Gladly, after a quick Google search for the difference, I came across this discussion, which clarified a few things.

So out of those you named:

  • APC is opcode cache and data store
  • APCu is only data store
  • OPcache is only opcode cache

Since APC is older, at the moment you likely want OPcache as well as some data store, not necessarily APCu (although it is perfectly fine choice).

My interest was in opcode cache, since I already had a data store.  Installing and configuring OPcache needed just a few seconds, and didn’t cause any issues so far.

And if you want more information about it, here is a useful article, which, among other things, lists the helpful tools for monitoring and tweaking OPcache configuration.

3. How to check if OpCache is actually caching my files?

If you have already installed and configured OpCache, you may find it important to control which PHP files are actually being cached. The whole cache engine works in the background and is transparent to a visitor or a web developer. In order to check its status, you may use one of the two functions that provide such information: opcache_get_configuration() and opcache_get_status(). Fortunately, there is a couple of prepared scrips that fetch all the OpCache configuration and status data and display it in a friendly way. You don’t need to write any code by yourself, just pick up one of tools from these below:
Opcache Control Panel,
opcache-status by Rasmus Lerdorf,
OpCacheGUI by Pieter Hordijk,
opcache-gui by Andrew Collington.

May the Cache be with you.