Tito Miguel Costa Blog2024-03-28T10:51:48+00:00Zend_Feed_Writerhttps://www.titomiguelcosta.comTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.com2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/git-workflowTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comI've started to use Git a few months ago, letting behind Bazaar. Nothing against Bazaar, it does the work as expect, no issues, but since GitHub hosts all the projects that I care, the switch came naturally.As long as I use a VCS, that's fine, can not image myself going back to the days where upload was done using an FTP client or even when rsync had its glory days.At the moment, in the projects I'm involved, I'm the only developer, so it is easy to avoid conflicts and no need to generate patches. My life doesn't get much complicated.When my project uses Symfony2, and that happens almost in every of my web projects, I initialize the project with composer and remove the original git repository and start one of my own.
# git repository initialization
$ git init
# ignore files
$ vim .gitignore
# add files
$ git add .
# first commit
$ git commit -am "Setup for project X"
Normally the next step is to configure the server where the project will be hosted.I created a git folder in /var and the project itself will be in /var/www.A folder with the same name of the domain that will host the project is created in both folders.
$ mkdir /var/git/example.com
$ mkdir /var/www/example.com
Next step it to initialize a bare repository so I can upload my local project into it.
$ cd /var/git/example.com
$ git init --bare
In my local machine, I do the first push after adding the remote hosting normally called server.
$ git remote add server git+ssh://user@example.com/var/git/example.com
$ git push server master
What follows is configuration of capifony, but since I already discuss it in a previous blog post, I won't repeat myself.When time comes to finally get my hands dirty and work on the project, I always do a pull, even knowing I'm the only one with access to the repository, I consider it a good practise.Right after, I do a composer update, commit the changes and create a new branch.If everything works as expected, and I achieve my goals, I do a final commit in the new branch, go back to master and merge.
# create a new branch to work on
$ git checkout -b new_feature
# add new files in case I created any
$ git add .
# git changes
$ git commit -am "description of what I did"
# return to master branch
$ git branch master
# merge the branches
$ git merge new_feature
# remove branch
$ git branch -d new_feature
I only tag my code when a new version is released. When that happens, I keep forgetting to add --tags to the push commands, if not done, tags will be only in local repository.
# adding tag
$ git tag 1.2.2
# push new version to server with tags attached
$ git push --tags server master
2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/conding-standardsTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comSince I'm mostly a Symfony programmer, I try to follow as much as possible their coding standards, although I do not sympathize with some of their decisions.There are mainly two points I disagree, for me:A line break before braces in control structures increase readability (already happens on classes and methods)I prefer to use underscores for the name of variables instead of the camel case notationSometimes I forget to follow the standards and it is boring to check back the code and fix it. Fortunately, there are a few tools that can help.PHP_CodeSniffer is a pear package that analyzes source code and reports the errors.One limitation of PHP_CodeSniffer is that it doesn't automatically fixes the errors reported, PHP-CS-Fixer for the rescue.PHP-CS-Fixer is a phar file that complements PHP_CodeSniffer, fixing our source code taking into consideration the standard that project follows.For last, there is NetBeans, with a simple ALT+SHIFT+F, it automatically formats code. You can download my whole configurations and import them in Tools > Options or use just this file just for PHP and Editor configurations (from NetBeans 7.2).With these three tools, there's no reason not to adopt a conding standard and implement it in your PHP projects.2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/debug-php-project-with-xdebug-on-netbeansTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comXdebug is a great tool to debug your PHP code, but make sure it is only used in your dev environment. It consumes a lot of memory and pages will load slower.First thing is to install it. In my Ubuntu 12.10 box it was as simple as running:
sudo apt-get install php5-xdebug
Then I had to configure Xdebug editing the file /etc/php5/apache2/conf.d/20-xdebug.ini. The file will look like:
zend_extension=/usr/lib/php5/20100525/xdebug.so
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_host=localhost
xdebug.remote_port=9000
xdebug.idekey="netbeans-xdebug"
xdebug.remote_log="/var/log/apache2/xdebug_remote.log"
Next step is to configure NetBeans. Check the properties of your project.Make sure the Web root in the Sources categories points to your public forlder, web in a Symfony2 projectIn the Run Configuration category, specify the name of your controller, in a Symfony2 project will be app_dev.phpClick on the Advanced button, and in the Debug URL, choose the Ask every time option. This way you can change the url to point to another location other than the index page.Insert breakpoints in your code with Ctrl+F8 or just click over the line number, a red square will show up.To start the debug, press Ctrl+F5 or click on the Debug Project button on the toolbar.Edit the URL of the page you want to debug and press Start. A new tab on your browser will open up and will remain blank. Get back to NetBeans play with Debug button on the toolbar.Everytime you reach a breakpoint, execution will stop and you can check on the debug window the values of your variables.Check out the official NetBeans webpage for more info.2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/deploy-symfony2-project-with-capifonyTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comDeployment is a very recurrent task and tends to be very repetitive and error prone when done manually.It gets even worse if your application is behind a load balancer and you have to deploy to several servers at once.Capifony comes to the rescue. It integrates easily with symfony1 and Symfony2 projects.Before using Capifony we must decide the strategy we will use to deploy our code. In the documentation they present two cenarios. First one is the one I use. My dev code is published to a central git repository that production servers have access.Here you have the sources I consulted to configure Capifony in my project.Official documentationServerGrove tutorial for shared hostsServerGrove tutorial for VPS hostsTutorial on how to deploy on multiple serversEven with all that documentation it wasn't easy for me to setup the config file will all my requirements, so I publish my final version:
#before "deploy:restart", "deploy:set_permissions"
before "symfony:composer:install", "composer:copy_vendors"
before "symfony:composer:update", "composer:copy_vendors"
set :application, "MyApplication"
# SSH settings
set :serverName, "www.example.com"
set :domain, "example.com"
set :user, "ubuntu"
ssh_options[:port] = 22
ssh_options[:keys] = ["/path/to/my/ssh/key.pem"]
set :deploy_to, "/var/www/example.com"
set :app_path, "app"
# Repository settings
set :repository, "git@bitbucket.org:user/example.git"
set :scm, :git
set :git_enable_submodules, 0
# Symfony settings
set :model_manager, "doctrine"
role :web, domain # Your HTTP server, Apache/etc
role :app, domain # This may be the same as your `Web` server
role :db, domain, :primary => true # This is where Symfony2 migrations will run
# Composer settings
set :use_composer, true
set :update_vendors, true
set :vendors_mode, "install"
namespace :composer do
task :copy_vendors, :except => { :no_release => true } do
capifony_pretty_print "--> Copy vendor file from previous release"
run "vendorDir=#{current_path}/vendor; if [ -d $vendorDir ] || [ -h $vendorDir ]; then cp -a $vendorDir #{latest_release}/vendor; fi;"
capifony_puts_ok
end
end
# General settings
set :shared_files, ["app/config/parameters.yml"]
set :shared_children, [app_path + "/logs", web_path + "/uploads"]
set :keep_releases, 3
set :use_sudo, false
set :writable_dirs, [app_path + "/logs", app_path + "/cache", web_path + "/uploads"]
set :webserver_user, "www-data"
set :permission_method, :acl
set :use_set_permissions, true
# Log level
logger.level = Logger::MAX_LEVEL
2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/integrate-zend2-packages-with-composerTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comIn case you use composer to manage the dependencies of your PHP project, it will be very easy to integrate Zend2 packages.Zend2 has its own repository, doesn't use packagist, so you will need to configure it in your composer.json file.
"repositories": [
{
"type": "composer",
"url": "http://packages.zendframework.com/"
}
]
After adding the Zend2 repository, you can easily download any of the packages available. All you have to do is specifiy it in the require section of composer.json file.
"require": {
"zendframework/zendgdata": "2.0.*",
"zendframework/zend-paginator": "2.0.*",
"zendframework/zendservice-flickr": "2.0.*",
"zendframework/zend-feed": "2.0.*"
}
2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/cache-data-in-symfony2Tito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comDoctrine provides a Cache Layer. A very good one, indeed. So if you need to cache data use Doctrine/Commons.This Cache Layer abstracts the caching functionality and provides already various different backends for your caching data.These are already build-in in the master version:APCArrayFilesystemMemcachePhpFileRedisWinCacheXcacheZendDataYou could even create your own on top of the CacheProvider class and the Cache interface.In your Symfony2 project simply register your cache service of choice and your ready to go.In your config.yml or services.yml add:
cache:
class: Doctrine\Common\Cache\PhpFileCache
arguments: [%kernel.cache_dir%]
And in your controller you can call the service and save and load data from the cache.
$cache = $this->get('cache');
$cache->setNamespace('mynamespace.cache');
if (false === ($cached_data = $cache->fetch($cache_key)))
{
$cached_data = $SOMEAPI->getData($params);
$cache->save($cache_key, $cached_data, 3600);//TTL 1h
}
As you can see you can set a namespace for your cache data, so that you can easy use it for different scenarions in the same app.Further you can set a time-to-live (TTL) in seconds as third parameter of the save method.So after all symfony2 has a caching mechanism for data, its just a little hidden in the Doctrine/Commons dependency.Original source2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/mysql-and-phpmyadmin-on-fedora-16Tito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comFor my surprise, after installing MySQL server, there was no service mysqld in /etc/init.d, so I could not start mysql server with the command /etc/init.d/mysqld startInstallating MySQL
# yum install mysql-server
So it seems that now, to start a service we must run the command systemctl.
# systemctl start mysqld.service
In case you want to enable the mysql when you start your computer:
# systemctl enable mysqld.service
Another thing that hit me by surprise is that phpMyAdmin doesn’t work out of the box, you need to configure some options.Edit the files /etc/httpd/conf.d/phpMyAdmin.conf and /etc/phpMyAdmin/config.inc.php (main one).In my case, I set a random string to the blowfish_secret option, changed auth_type to cookie instead of the default http, and changed to TRUE the option to allow no password (AllowNoPassword).After a restart of the apache server (# systemctl restart httpd.service), I was ready to go.2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/avoid-password-prompt-on-the-command-lineTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comIn case you often connect to remote server and get bored of typing the password all the time, there is a solution.Create a public key, running the command
$ ssh-keygen -t rsa
A file ~/.ssh/id_rsa.pub will be created with your public key.Now, publish the key to the server
cat ~/.ssh/id_rsa.pub | ssh USER@DOMAIN.COM "cat >> .ssh/authorized_keys"
And this will be the last time you will be asked for the password. Test if everything went as expect executing
ssh USER@DOMAIN.COM
You should login immediately, without being asked for the password.2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/google-chrome-fonts-fixTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comGoogle Chrome version 7.0.517.44 in my Fedora 13 box renders fonts in a funny way even after the instalation of the windows fonts.Fixed the problem creating the file ~/.fonts.conf with the following xml code:
<match target="font">
<edit name="autohint" mode="assign">
<bool>true</bool>
</edit>
<edit name="hinting" mode="assign">
<bool>true</bool>
</edit>
<edit mode="assign" name="hintstyle">
<const>hintslight</const>
</edit>
</match>
2024-03-28T10:51:48+00:002024-03-28T10:51:48+00:00/blog/custom-parameters-in-a-symfony2-projectTito Miguel Costawebsite@titomiguelcosta.comhttps://www.titomiguelcosta.comIn symfony 1.* we had app.yml, so we would define custom parameters and access them anywhere with the get static method of the sfConfig class. In Symfony2, there is no such thing as app.yml. In case we want to define custom parameters, we create a new file in app/config, for instance, settings.yml or settings.ini, an include it in the config.yml as an external resource (we could use the existing file parameters.ini, but not to mess up, I prefer to use a different file).So, in config.yml (or just in config_dev.yml if you prefer to make it available only in the dev environment)
imports:
- { resource: settings.yml }
In settings.yml define your parameters:
parameters:
shared_folder: '/home/shared'
To access this parameter in a controller:
public function indexAction()
{
$shared_folder = $this->container->getParameter('shared_folder');
}