Walking on the Drupal lane
My name is Panagiotis Moutsopoulos and I am the most recent member of the Netstudio.gr team. I have been part of this great team for a few months but I never had the needed time to say "Hi!". Wondering about what I should write, I thought of what Ernest Hemingway used to think: “Do not worry. You have always written before and you will write now. All you have to do is write one true sentence. Write the truest sentence you know".
So, I've been a member of Drupal.org since 2009 but my first contact with Drupal was a few years before that, back in the 5.x era. I had just reached the end of my studies in university (Information Technology in the Technological Institute of Athens, actually) and I was used to build websites from scratch using plain PHP and MySQL. Well, Joomla existed but I still preferred using custom code. It might be that I didn’t like Joomla’s logic or that I had to pay money for some modules. The fact is that in a colleague’s screen I saw the Garland theme with the Druplicon. It was kind of weird. It seemed so weird that I wanted to explore it. What it is, what it does, who uses it and why! All these questions filled my mind and since I was used to check the various web applications found in the Ubuntu repositories (like EGroupware for example), I thought of testing the Drupal system too.
Long story short, I started reading the docs, hacking the core (and understanding why this is a bad thing!!!) and developing my custom modules from defining simple hook_form_alter()s to implementing payment methods for the Ubercart ecommerce system or processing images using the PHP GD image library. I also learnt jQuery in the process. So, after being burnt and having got my hands dirty many times with what I did wrong, I decided to write below a few statements and a few advices. Some of them are meant to be read from anyone in the WebDev community, whereas others are meant only for the Drupal community.
1) Don't ask for the solution. Discover it!
(if you have the time)
We will always find bugs in the code. May it be a module that doesn't do what it says, may it be a library that has a conflict with custom code. Bugs are always bound to survive and developers are bound to always be there to fix them. From the smallest function to the largest framework, everything comes down to basics eventually. In most cases, someone will have already asked the same question and you will be able to find it with a simple Google search or a more focused one like in StackOverflow or Drupal Issue queues.
Do not forget: There are times that it is needless to reinvent the wheel. If what you are trying to do is so extreme, or you will need more time doing it than having a benefit from the experience, it might be better if you asked a colleague. Just make sure you dedicate some time later on understanding how the code you may have copied works.
2) Don’t improvise! Use the tools you have!
(or at least have a knowledge of them and when you have to use them)
From a simple programming language to a full framework, the developer has some tools at his disposal and must know how to use them. If you know for example that the PHP function array_slice() exists, you will most possibly avoid for{} loops until a certain index is reached. On the same track, if you know that there is an entity_load() function in Drupal, you will most certainly avoid querying the tables of the database to get the values you need. When choosing a toolbox, we use to choose it for the tools it offers and not for the wood or the iron we can get if we disband the hammer.
Do not forget: There are times that you will not able to do exactly what you want to. There are also times that if you do it the framework-way the whole process will take longer. For example, if you need the title of a node in a Drupal single-language website, using node_load() just for this might be a bit excessive. You could just db_select() or even better db_query(‘SELECT ...’) the node table. If you have knowledge of the tools you have in your possession, you will be more flexible. I wouldn’t want to give the benefit of flexibility away. Would you?
3) Check the server! Check the version! Beforehand!
(or upgrade if necessary)
When developing a new website or adding new features to an existing website, make sure that the client has specified the supported browsers and that the hosting company has specified the possibilities of the server. If the client needs IE6-support, in case of an intranet site where the users haven’t upgraded their Operating Systems for a very long time for example, you might want to make sure no border-radius or box-shadow or any other hocus-pocus CSS exists in your code. Hocus-pocus for the Middle-Aged IE6 that is... If you add features to a pre-existing website, you might also want to check its software version. May it be a JS or PHP framework, you must take the version into account. For example, the entity_language() function in Drupal was added in version 7.15. If you need this function and the website is built upon a version prior to 7.15 you should consider upgrading. On the other hand, make sure your production server has the same packages installed as your development server. It would be terrible if you couldn’t use file_get_contents() to get the contents of a URL you need because the hosting server is a shared plan and the allow_url_fopen setting is set to false.
Do not forget: You won’t be able to please everyone. You may get anxious, you may struggle to make everything work correctly with what the client and the server offers you, you may try again and again but some things are not meant to be. If you are sure you will get the job done much easier using a version of PHP >5.2, you’d better talk with your client about investing on an upgraded server.
4) Gain the experience of the Drupal or similar application process!
(even if it takes sometimes long)
I have the experience of the Drupal application process but I’m sure there are others like this too. It was easy to start developing a module. This part is always easy. I even remember a speaker in a conference telling us that it is much easier to forget security in web applications than in desktop applications. Web languages offer the possibility of displaying your content immediately and when you see immediate results, you can always say «Since it executes and displays correctly, it’s ok», but clearly it’s not. Till now, developing a custom module in Drupal is almost like writing a function or two {which are mostly hook_alter_*() functions} in a .module file and enabling it. After my experience with the Drupal application process, it seems this isn’t just that. There are coding standards that you won’t be able to miss if you want your module published in the community. My experience was with the UC Clear Roles module of Drupal 6 and there were many things I had missed. For example, when creating menu items through hook_menu() functions, you don’t need to enclose your string in t(). The system does it by itself and using t() over the default t() is just plain wrong. The website will still work. But you will have some translation issues. Other than that, I also discovered the Coder module.
Do not forget: Sometimes it may seem harsh when having done a great work and people tell you that you have to correct the comments and the lines that exceed the 80 characters-limit. Don’t take it too hard. There is a reason behind this. You won’t be able to understand the “why” until you succeed but it is definitely worth it.
5) Check how the core developers have made it!
(and file a patch if it’s faulty)
If someone knows how to do it better than anyone, it must be the core developers. They are the ones who created all the tools you have in your hand to start building your application. Check the code of a core module of the system you are using and get a glimpse on how the core developers have written their code. Don’t expect to start developing and implementing a new payment method in Drupal Commerce without having at first looked the DC core module implementing the Paypal method. You may succeed but it will be painless and useless.
Do not forget: Sometimes you will find bugs in the core documentation or modules. Don’t just fix the problem in your local environment without informing the developers. In Open Source systems especially, their power is the power of contribution from the community. Even if you don’t care about the community, at least think of this: If you don’t fix the problem, you will encounter it again in the future.
6) New technologies mean new possibilities!
(sometimes new troubles too)
Being a developer is not something you study in university and after graduation someone will tell you “That’s it! You ‘re ready! Congratulations!”. It definitely doesn’t go this way. Using document.getElementById() function when you have jQuery or any other JS framework loaded is like using the copy con DOS command to write a text file when all those editors exist out there. It’s worthless unless you want to add a Google Map in your application or if you are studying JS from zero point. You have to learn new technologies and test them. Clients will learn about them and ask for them. You can’t just say “I have studied B and in B I believe” when it has been overlapped by C and C++.
Do not forget: It’s not possible for a human being to study all and every new technology. You will get anxious and eventually give everything up. When having your first steps is when you need to get a glimpse of everything. After deciding your field of knowledge, you‘d better stick with it and just evolve and advance in it.
7) Secure your database! Secure your code! Secure your input!
(anyway you can)
Most web applications at this time require a database system to store their information. I’ll start from the basics. The user passwords should not be plaintext. You should encrypt them and then store them. If not even the administrator of the website may make the system reveal a user’s password, then this gives the system an integrity bonus. Another thing you should make sure when developing an e-shop system and the client needs credit card details stored in your system is this: make sure you store the data encrypted. No, MD5 algorithm won’t suffice. You should better consider using a salt algorithm for this kind of data. Just make sure your salt is not hard-coded but, instead, included in your code from a file outside your website’s root folder. You should also consider securing your code. Drupal modules are mostly functions doing nothing if you’re not Drupal. CSCart uses another mechanism for its files: it looks for a constant normally defined in its index file. If it’s undefined, die() is invoked and the process stops. Drupal’s contributed modules don’t have any .php extension too. One of the benefits of this, is that the developer may include them in his/her code but no one will be able to execute them since Apache only knows about .html and .php files. Files with a .module or .inc extension are no candidates of being executed.
Do not forget: Drupal has this simple but powerful function called check_plain(). It’s actually just a wrapper around the PHP built-in htmlspecialchars function but it gets the job done well enough. I have even found myself copying this wrapper in other systems to make sure the values the user submitted are going to reach the database without breaking anything. Well, dangerous strings will break but that’s a good thing I can assure you.
8) Cache what you can!
(don’t overdo it though)
From basic PHP to frameworks like Drupal, there are some mechanisms and some ways of caching the data you once produced in the same page request, in the session or somewhen in the past. For example, if a function returns a HTML string and doesn’t take any arguments, you might want to use the static keyword to declare the variable holding the output and return this when non-empty instead of recreating the value. You might also want to store values in the $_SESSION variable, like the email, the full name and other personal details, to prepopulate the fields the user has already filled but left the form page. Drupal also offers various mechanisms for caching forms, blocks, entities, views and other elements in database and these values can be used later in the day to save regeneration.
Do not forget: Don’t overdo it! Using static variables increases the memory footprint and using the $_SESSION variable to store HTML is not the best thing to do. You can always store the values you need in session and have a HTML template file for the static content.
9) Run cron outside Drupal!
(or even more outside)
Drupal 6 without Poormanscron module required a cron job to make the website’s cron run. In Drupal 7 this is no longer required since every time a user views your website, if a certain time has passed since the last time, cron will run. This has some drawbacks though. This means that the visitor running cron will have a slower response. This also means that if no one reaches your site for a certain day, cron will not run. To avoid all this, or if you need cron to run every minute for example, you should set a cron job from an external source. As for how to do this, you should consider checking the drupal docs.
Do not forget: Drupal runs each module’s hook_cron() based on the module’s name and weight. If a module’s cron execution takes longer than desired, you have at least two ways of solving your problem. One way is to create an external file which will include the drupal bootstrap and call from there your desired function. You may find information on how to do that in Navin S Nayan’s blog. The other way is to install and enable contributed modules like Elysian Cron or Ultimate Cron and decide how often each hook_cron() will get executed. This way, you may set, for example, the core’s functions to get executed once per hour but your custom module’s hook to get executed every five minutes.