code segment too large
A web development blog by chmielot
Tuesday, March 10, 2015
FollowSymLinks problems with Plesk and Strato Web Hosting: Symfony2 - symbolic links for assets
My projects are located on a Strato server and I'm running Plesk 12 on it to manage the websites. In the past I already had trouble with different configurations overwritten or managed by Plesk, so my first guess was to check the website settings in the Plesk admin panel.
Following the Parallels KB article 27 I added the FollowSymLinks option to my projects web directory:
I tried different combinations of options and directories but none of them worked. One of the other options was -SymLinksIfOwnerMatch.
The config file which is actually edited by entering the additional HTTP server directives in Plesk is located in /var/www/vhosts/system/mydomain.tld/conf/vhost.conf. The next step was to verify that my customised vhost.conf file was actually loaded by entering invalid directives and running the apache config check. Still no success.
I made sure that the symlinks and the target directories are readable and executable. Using the following code I checked which user the webserver is running as:
I made sure that the user has read and exec rights on all of the paths and files. The error message in the log was still there. Analyzing it again I could state that the link target is for sure accessible and that symbolic links are definitely allowed!
Finally I checked the apache envvars configuration file in /etc/apache2/envvars and noticed that the webserver user and group are both www-data. Then I remembered that the current apache user is depending on the hosting account of Plesk, because PHP is running as a (Fast)CGI application. Maybe apache is trying to follow the symlinks as www-data user...
My project files all belong to the respective hosting account user. The group is always psacln which is a special Plesk group. Adding the psacln group to the www-data user solved the problem!
Sunday, February 3, 2013
Symfony2 - Customize output of expanded form choices
The data for the checkboxes is taken from the database, so I'm using the 'entity' type in my form:
public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('cities', 'entity', array( 'class' => 'MyCityBundle:City', 'query_builder' => $this->queryBuilder, 'required' => false, 'expanded' => true, 'multiple' => true, )) ; }
Thursday, October 25, 2012
sf2 input type date - disable native datepicker
Newer versions of the Google Chrome browser (and perhaps Firefox will follow) implement their own datepicker on input fields with type="date". This seems to be some new fancy HTML5 feature, but correct me if I'm wrong. If you are using jQuery datepicker throughout your whole project for example, you suddenly have two datepickers on that input field.
There is no possibility to turn off the native datepicker with additional attributes. You are left with three solutions to your problem:
- Use modernizr to detect this feature and only enable jQuery datepickers, if not present:
- Prevent standard event handling on this kind of input types: which I don't think is a good solution!
- Render all form fields of type date with type="text" in symfony2. To enable this globally, register a global form theme in your config.yml as described in the Symfony2 documentation. My form theme consists of the following Twig code: This overwrites form_widget_simple and checks for the registered field type before setting it for the input field. If it finds 'date' it is overwritten with 'text'. Very nice and quick solution in my opinion, hope that helps you.
Thursday, May 17, 2012
Sublime Text 2 - Snippet to create get/set methods
Sublime Text is a sophisticated text editor for code, html and prose. You'll love the slick user interface and extraordinary features. (www.sublimetext.com)
Its snippet system allows you to create snippets that are triggered by a sequence of characters you can define, followed by tab key. The syntax is really easy. To create a snippet choose "Tools, New Snippet".
The snippet I'd like to show you today is a huge timesaver. I use it excessively in my form models in symfony2. After declaring a model variable as private or protected I need to create a get and set method for it. Copy paste and substitute the variable name was my choice until today. The following snippet allows you to use the following workflow:
- type 'getset'
- press the tab key
- type your variable name
- done.
The result:
Sunday, November 13, 2011
Many to many search with doctrine2 and symfony2
While experimenting with many to many relations I encountered how to easily retrieve all users that are associated with a certain work category. Many to many relations in doctrine create a relational table between two entities, which is no entity itself. You cannot use the table to create joins. I'd like to cite the doctrine2 orm reference:
"Why are many-to-many associations less common? Because frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes."The association class is your third entity which you can use to create your search queries using JOINs for example.
In this case we have a pure many to many relationship. I built a form with an element of type entity which represents the work categories.
As this draws a multiselect control with the ID of the work categories as value on submitting the form, you have access to them in your search query. The key is to use "MEMBER OF" then:
Surprisingly for me, this creates a very similar query as I used for the one-to-many search query:
AND EXISTS (SELECT 1 FROM users_workcategories u2_ INNER JOIN user_work_category u3_ ON u2_.workcategory_id = u3_.id WHERE u2_.user_id = u0_.id AND u3_.id = ?) AND EXISTS (SELECT 1 FROM promoters_workcategories u2_ INNER JOIN user_work_category u3_ ON u2_.workcategory_id = u3_.id WHERE u2_.user_id = u0_.id AND u3_.id = ?)
Doctrine is aware of of the third relational table and uses it for JOINs to assemble the native SQL query that looks far more complicated than the DQL string. For people not familiar with advanced SQL queries, this is a live safer. On the other hand, SQL people surely need to be argued into this new approach.
Saturday, November 12, 2011
Search form using symfony2 and doctrine2
Next thing you do is writing a template for your form and to specify some validation rules. My controller action which receives the search POST looks like this:
We need to implement the findBySearchCriteria function in the empty repository class of the user entity. This function returns a query builder object which we can do everything we want with.
The following examples show what is possible with the doctrine2 query builder in the search function.
Many-to-one search
The user has a languages attribute which is of type Language. The entity Language has three attributes:- a language name (e.g. english, french, etc)
- points that define how good the language is spoken by the user (10 very good, 1 very bad)
- a back reference to the user
As "exists" in the query builder expects a dql subquery, we give it one.
"u" is the alias for the User class of the main query builder. The same method is used for the french language points.
The resulting DQL is:
SELECT u, l FROM Acme\UserBundle\Entity\User u WHERE (EXISTS( SELECT langE FROM AcmeUserBundle:Language langE WHERE langE.user = u AND langE.language = :langName AND langE.points BETWEEN 10 AND :points))
Nested AND / OR queries
Next requirement is that the zip code of the user entity has to lie in a given range of zip codes. The user who defines the search criteria is able to provide a list of zip code ranges. The format for a range is "xxxxx-xxxxx", so a zip code consists of five digits.The zip code range search query needs to be built using OR. The user's zip code can lie in one range OR another. Native SQL could look like this:
WHERE (zipCode BETWEEN :zipCodeFrom1 AND :zipCodeTo1) OR (zipCode BETWEEN :zipCodeFrom2 AND :zipCodeTo2)
To combine this with the language query, the OR part has to be nested within an AND part:
WHERE ((zipCode BETWEEN :zipCodeFrom1 AND :zipCodeTo1) OR (zipCode BETWEEN :zipCodeFrom2 AND :zipCodeTo2)) AND (EXISTS( SELECT ....To accomplish the OR nesting you can use add() on the orx expression. The following example shows how to do that:
This results in a really nice nested query like this:
SELECT u FROM Acme\UserBundle\Entity\User u WHERE ((u.zipCode BETWEEN :zipFrom1 AND :zipTo1) OR (u.zipCode BETWEEN :zipFrom2 AND :zipTo2)) AND (EXISTS( SELECT langE FROM AcmeUserBundle:Language langE WHERE langE.user = u AND langE.language = :langName AND langE.points BETWEEN 10 AND :points))
Building nested queries is really easy. It took me some time to find out that I can use add() on the orx expression to dynamically add parts to it.
Friday, October 29, 2010
Notes on Zend SOAP webservice development
WSDL caching
While developing a webservice application do not forget to disable WSDL caching, e.g. in your php.ini configuration file.soap.wsdl_cache_enabled=0
Set path to SOAP server in WSDL file
When you use a controller for your webservice and desire to have two actions, one for the automatically generated WSDL file and one for the server, use the setUri method of the Zend_Soap_AutoDiscover class to set the URI of the server.$wsdl->setUri('http://example.localhost/index/soapserver');
Error handling
Error handling with exceptions is easy. I suggest to create your own Exception class first, it can be empty for now:In your webservice class throw your new exception on invalid input for example.
On SOAP server side, you have to register your Exception class:
On Soap client side embed your request in a try - catch block:
Which for example outputs: 'SOAP ERROR: [Receiver] The product ID does not exist!'
The code
The webservice controller:The webservice class:
The custom Exception class: