Category: open source

rss

Fixing compiling issues with magnet.c

Jan Kneschke maintains lighttpd and posted a simple FCGI for lua. This magnet.c should be easily compiled with

1
gcc -Wall -O2 -g -o magnet magnet.c -llua5.1 -lfcgi -ldl -lm

This may not work if your lua-include is not in the path for compiling.

And you'll run into such error messages:

1
2
3
4
5
magnet.c:3:20: error: lualib.h: No such file or directory
magnet.c:4:21: error: lauxlib.h: No such file or directory
magnet.c:11: Error: expected »)« before »*« token
magnet.c:19: Error: expected »)« before »*« token
magnet.c:59: Error: expected »)« before »*« token

Since you may not be used to compiling, I think it might be good to post a reason for that and a solution.

The reason is, that lualib.h is not in include path. To add it specific folder for the compiling to the include path you may use the -I /path/name/ parameter.

1
gcc -Wall -O2 -g -o magnet magnet.c -I/usr/include/lua5.1/ -llua5.1 -lfcgi -ldl -lm

There are some distributions, where the -llua5.1 may not work and result in cannot find -llua5.1. In this cases try -llua instead.

Have fun compiling!

In open source & Lua By DracoBlue @ 21:28 19.03.2009

Detect action/view/module and matched route in agavi

de en

For each executed Module/Action(+View) there is an ExecutionContainer (AgaviExecutionContainer). So if you want to retrieve the current executed action, module or view, best is to do

1
2
3
$action = $this->getContext()->getActionName();
$view = $this->getContext()->getViewName();
$module = $container->getModuleName();

But what if you want to retrieve the "real" action, the one and only for the request? That's a little bit more difficult, so here a short introduction how to deal with that.

Whenever the routing of agavi does the work for you, by turning the input data and webbrowser call of a user, into a action and validated data, it triggers an action, executes the view for the outputtype and fills the template. But Slots can be used from the view and trigger then again validation+action+view for their parameters.

This is why the real request route can not be found in the execution container and must be found somewhere else. In the Request.

1
2
3
$route_names = $this->getContext()->getRequest()->getAttribute(
'matched_routes', 'org.agavi.routing'
);

The route_names is nothing but an array, for instance:

1
2
3
4
5
array(
'product.edit'
// because our current route is named "product.edit"
// in routing.xml
)

This information does help us indirectly to determine the action, which got called! Since the WebRouting has also a getRoute-method, which expects just a route_name, we can retrieve the info now easily:

1
2
3
4
5
6
7
// we want to have just the first one,
// thatswhy list($first) = $array style
list($route_name) = $this->getContext()->getRequest()->getAttribute(
'matched_routes', 'org.agavi.routing'
);

$route = $this->getContext()->getRouting()->getRoute($route_name);

The new $route-Variable now holds an array of all information about the route. In our case, just some are interesting.

1
2
$module = $route['opt']['module'];
$action = $route['opt']['action'];

One really should use that only in case of a default slot, which is used directly in the output_types.xml or used on serveral different pages and has to determine on its own and by using module+action where it's actually embedded.

In open source, php & Agavi By DracoBlue @ 22:26 05.03.2009

PDT auto completion tips (for agavi)

de en

In PDT (php development tools for eclipse) you are able to do auto completion (e.g. ctrl+space) on most of the classes, as long as they are defined properly or you have a proper php-doc set up. Check that tutorial, if you want to set up PDT.

Graste posted a snippet, which tells eclipse for the project (in this example it's agavi) that the variables (which are common for templates), like $template (or $ro, $rd and so on) are defined with correct type.

Here is a slightly modified autocomplete.php:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
exit();
$slots = array();
$template = array(); // agavi 0.11 default
$t = array(); // agavi 1.0 default
$tm = new AgaviTranslationManager();
$ro = new AgaviWebRouting();
$rq = new AgaviWebRequest();
$ct = new AgaviController();
$us = new AgaviSecurityUser();
$rd = new AgaviWebRequestDataHolder();
?>

Just save that file to autocomplete.php in your project structure -> eclipse will use this classes as default, so you have neat auto completion even in agavi templates.

If you have return type for a function, and want the caller to be able to autocomplete: just use proper php-docs. For example, the following will give SomeClass-typed elements on a function test123:

1
2
3
4
5
6
/**
* @return SomeClass
*/
function test123() {
/* ... */
}

If you just want autocomplete for a specific scope, you may use the following:

1
if (false) $instance = new SomeClass();

or better

1
/* @var $instance SomeClass */

and auto completion on $instance will work like if it was a SomeClass.

Got another tip? Feel free to add it in the comments!

In open source, php, Agavi, Eclipse & PDT for Eclipse By DracoBlue @ 18:54 23.02.2009

Preloading CSS-images for :hover

de en

The top navigation here at dracoblue.net is done with css images, which also have a :hover-effect (showing a lighter version of the image).

So there is a:

1
http://dracoblue.net/style/menu_news_hover.png

and a

1
http://dracoblue.net/style/menu_news.png

In CSS it looked like that:

1
2
3
4
5
6
a#newsLink {
background: transparent url('menu_news.png') no-repeat;
}
a#newsLink:hover {
background: transparent url('menu_news_hover.png') no-repeat;
}

All this is quite common, but I was facing a usability problem here. The *hover.png files won't be loaded until one of the links got hover'd. In the perspective of the server owner, you might be happy about that. But for the user, the image is unavailable for nearly a second, because it takes time to deliver the image to the user.

So here is my solution to preload the image (without using javascript or stub-<img>'s).

1
2
3
4
5
6
7
8
9
10
11
12
13
td#newsLink a {
background: transparent url('menu_news.png') no-repeat;
}
td#newsLink a:hover {
background: transparent url('menu_news_hover.png') no-repeat;
}
td#newsLink {
background:
transparent
url('menu_news_hover.png')
fixed no-repeat
-120px -120px;
}

I moved the #newsLink to the td surrouding the newsLink. And at the end, I added a new decleration for a non-repeating and - with coordinates -120x-120 - clearly invisible image.

In open source, HTML & CSS By DracoBlue @ 09:55 23.02.2009

Concat multiple references as one imploded column (mysql)

In my blog I have the following structure (short version):

1
2
3
entry = id,title
category = id,name
entry_in_category = category_id, entry_id

I want to query for the following:

1
2
3
4
id | title | categories
---------------------------------
1 | My Entry | php,mysql
2 | Second ... | mysql,java

So if you want to get all entries with the corresponding categories you may do a refetch on each of the entries id in the entry_in_category table. But if (for example for tags) you really just want to have the name of the categories and nothing more, here comes a pretty gentle way to solve that issue.

1
2
3
4
5
6
7
8
9
SELECT
e.id, e.title,
(
SELECT GROUP_CONCAT(c.name)
FROM entry_in_category e_i_c
LEFT JOIN category c ON c.id=e_i_c.category_id
WHERE e_i_c.entry_id = e.id
) categories
FROM entry e

This solution uses the GROUP_CONCAT function, which was intruduced in mysql 4.1 and concats all results name-fields (oviously not grouped by anything) into a single string.

By default mysql concats the entries by using a ',' but you may use a different seperator by replacing the group-concat-part with the following:

1
GROUP_CONCAT(c.name SEPARATOR '-')

Thanks to Christian for bringing up a similiar issue, hope that solution helps you to get an idea on how to deal with similiar cases.

In open source & mysql By DracoBlue @ 13:27 21.02.2009

UTF-8 connections with Propel in Agavi

If you want to override the propel configurations for charset (encoding) for the connection you usally set the settings['charset'] value to for example utf8.

But if you are using agavi you want to configure propel properly by using agavi's databases.xml.

So after trying a while, here is how you can set the charset (magic is bold):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="UTF-8"?>
<ae:configurations
xmlns:ae="http://agavi.org/agavi/config/global/envelope/1.0"
xmlns="http://agavi.org/agavi/config/parts/databases/1.0">
<ae:configuration>
<databases default="propel">
<database name="propel"
class="AgaviPropelDatabase">
<ae:parameter name="config">%core.app_dir%/config/propelproject-conf.php</ae:parameter>
<ae:parameter name="overrides">
<ae:parameter name="connection">
<ae:parameter name="dsn">mysql:dbname=icanhazagavirelease;host=127.0.0.1</ae:parameter>
<ae:parameter name="user">w00t</ae:parameter>
<ae:parameter name="password">not_default_pass</ae:parameter>
<ae:parameter name="settings">
<ae:parameter name="charset">
<ae:parameter name="value">utf8</ae:parameter>
</ae:parameter>
</ae:parameter>

</ae:parameter>
</ae:parameter>
</database>
</databases>
</ae:configuration>
</ae:configurations>
In open source, php, Agavi & Propel By DracoBlue @ 21:06 18.02.2009