tricks

Changes Since Last Push in Git

The "git status" command only shows uncommitted changes locally. But what if we need to see "what files would get pushed if we did a push now?". The answer is not trivial (and no, "git push --dry-run" is not useful since it does not show changed files).

I've been looking for an answer, and since I am no git expert, it took me a while to find one, until @iosebi came to rescue. Apparently, what you need is this line of code:

git log origin/master.. --stat

Thank you, @iosebi! I probably hate git a little less, now :)

Replace a Function Name in Drupal Source Files

> perl -i -pe 's/oldname_/newname_/g' `find | grep "\.module$"`

Or if you want to first check the results:

> perl -pi.bak -e 's/oldname_/newname_/g' `find | grep "\.module$"`

which will create backup of original files. Those you can delete later with:

> find . -name "*.bak" -exec rm -rf {} \;

You can replace ".module" with ".inc" or "tpl\.php" if you also need those processed

SVN: Restore Deleted Folder from a Revision

Imagine a situation: you accidentally "svn removed" an entire directory tree from SVN. If the tree contained uncommitted code you can restore it from the backup, but you also need to restore things that were in the SVN. You can approach it multiple ways, but arguably the cleanest way is to simply revert to the revision before the deletion.

How do you do that in Subversion? The answer to this is quite short, but not necessarily obvious, so following is the list of example commands:

svn co -N SVN_PARENT_URL  . 
svn copy SVN_URL@REV FOLDERNAME
(Add-in or modify here any files that were not committed, before deletion)
svn commit -m "restoring" FOLDERNAME

example:

svn co -N https://svn.ex.com/repo/project/parentfolder@7537 . 
svn copy https://svn.ex.com/repo/project/parentfolder/deletedfoldername@7537 deletedfoldername
(Add-in or modify here any files that were not committed, before deletion)
svn commit -m "restoring" deletedfoldername

Sane Backtrace in PHP

PHP error messages are quite helpful, most of the time. Sometimes they do fall short of telling us what went wrong, however. It's especially common when and if you use a development framework (e.g. Drupal). Frameworks often do output buffering and/or code eval()-ing, making debugger output incomprehensible.

In such cases PHP's debug_backtrace() function is a real savior. debug_backtrace() is also very helpful if you want to look at the execution stack in a complicated code, to better understand the code. This function shows the execution stack that lead to the current function and does it pretty well... "too well" sometimes :) Out-of-the-box version of the function shows the list of invoked functions, source files they belong to, line numbers in the source file and the argument values being passed. The latter can be a huge problem, if code is passing around large variables. Output on the screen may get so garbled (esp. if HTML is used in variables) that the entire exercise may lose its meaning.

Short snippet below sanitizes debug_backtrace() output to make it slimmer and more comprehensible:

$trace = debug_backtrace();
foreach ($trace as &$t) {
  unset($t['args']);
}
echo "<pre>".print_r ( $trace,true)."</pre>";
exit();

How to Delete All Tables in a MySQL Database

If you are working on a system with somewhat large number of tables, you probably have wanted to delete a number of tables matching a pattern (dropping all tables is a specific case of this one). You can do that, by creating a very simple stored procedure:

mysql> delimiter $$
create procedure drop_tables_like(pattern varchar(255))
begin

SELECT 
@drop_sql:=concat('DROP TABLE IF EXISTS ', group_concat(table_name)) 
drop_statement
FROM information_schema.tables
WHERE table_schema=database() and table_name like pattern;

IF (@drop_sql IS NOT NULL) THEN
  PREPARE stmt from @drop_sql;
  EXECUTE stmt;
  DROP PREPARE stmt;
END IF;

end$$
delimiter ;

then you can use this procedure to mass-delete tables like:

mysql> call drop_tables_like ('ika%');

CSS Background Transparency

The Right Way is obviously CSS 3.0: rgba(R,G,B,ALPHA), but since only Safari supports CSS 3.0 currently (to the best of my knowledge, but you bet IE does not) the "right way" is out of question.

Moving on.

You can, also, try using the combined CSS properties:

filter:alpha(opacity=50);-moz-opacity:.5;opacity:.5;

and think to yourself: "OK, I used three properties for one thing, so the cross-browser demons should be happy, right? What can possibly go wrong?"

Well, demons are demons because they are evil and more goes wrong than possibly could. Namely, all child elements of the div, the background of which you just made transparent, will also become transparent. Even if you have no children divs: all your text, within the div, will be transparent and I can bet that was not something you wanted!

What to do? What to do? You rush to Google and find all kinds of MMFW-CSS (make-me-feel-worse, CSS) tricks that do not help. Like the one suggesting the inside elements should not really be children of the initial div, but be overlapped using, nothing less than, an absolute positioning. Yeah, like that really helps: adding the pain of absolute positioning to the already existing list of pains with your page's CSS!

But do not despair! There's a way to the light!

With no further delay, here is the workin'-kickin' solution, tested in most browsers:

Install PHP 5.2 on CentOS 5.2 Using Yum

Yum is a standard installation utility for CentOS 5.2. One of the reasons I favor CentOS over other Linux distros is actually because it comes with yum. It is that good!

Unfortunately, CentOS 5.2 does not generally include the latest versions of libraries, because it follows conservative path of the RedHat Enterprise. Which is not that bad of an idea, for a server OS... until you need that latest version of something and you are stuck... or: not necessarily.

If you a are a Drupal developer, there's a very good reason why you need the latest version of PHP: 5.2. The reason is called FileField module. This module is required by another absolutely essential module ImageField making it a matter of life-or-death (just kidding) to have PHP 5.2 on your server. But the latest CentOS release (ironically also 5.2) only comes with PHP 5.1.6.

What to do?

High Quality Youtube Content: URL Trick

Nice trick: add "&fmt=18" to a YouTube URL and you can enjoy stereo audio and better-quality picture (requires more bandwidth, of course).

Have fun

Extreme Form Handling in Drupal

Via: AgileApproach Blog

Drupal Form-Handling support goes far beyond just the documented part of so-called Forms API. You can do pretty much anything with forms in Drupal and you can use/display the forms anywhere.

Here is an example. Let's assume we want to construct a custom node type with custom fields, using CCK. Then we want to display this form into some non-standard page. To further complicate things, let's assume we also want custom verification and processing routines.

And last but not least - we want to use full power of Drupal and write a minimal amount of code. Following is a snippet demonstrating key points to achieving this task (thorough understanding of Drupal is required):

How to Hack "Read More" in Drupal

As you know Drupal displays the "Read more" link among all other after-teaser links in the blog postings view. This is not a usual user-experience. Most users expect "read more" link to be right after the teaser part of the posting. It can get confusing, so following is a quick-n-dirty hack that can fix it for you:

Locate the piece of code in node.tpl.php where it reads like:

 <?php print $content ?>

Put the following right after it:

<?php
// Extract "read more" link from $links so we can display it separately.
if (preg_match('!<a[^>]+>'.t('Read more').'</a>!', $links, $match)) {
  $links = preg_replace('/<a.+?href.+?>'.t('Read more').'<\/a>/i', '', $links);
  $more = '<div align="right">'. $match[0] . '</div>';
  $more = str_replace ("Read more", "Read the rest of the posting...", $more);
}
else {
  $more = '<span class="readmore-fill"></span>';
}

if ($more) { print $more; }

?>
Syndicate content