eZ publish - Disable ezinfo with .htaccess

The ezinfo module exposes the version number and other key information about an eZ publish installation.

It can be disabled through the eZ publish settings by adding these lines to override/site.ini.append.php:

[SiteAccessRules]
Rules[]=access;disable
Rules[]=module;ezinfo

An additional level of protection can be achieved using a RewriteRule, like so:

RewriteRule ^ezinfo.* http://domain.com/ [L]

In this case, requests for ezinfo will redirect to the home page, in effect they will appear to be ignored.

Other endpoints which may be used:

  • A server level 403 (access denied) or 404 (page not found) page. If this is the only page that gets these errors, people will still know it is an eZ site.
  • The ‘Error kernel (20)’ page, if it has been customized to act as a 404 page. Ending on this page, without customizing it doesn’t achieve much, since people familiar with eZ will be able to identify it as an eZ system by the message text.
  • A redirect off the server, strictly to frustrate the requester.
  • A bogus page with false information, which may be helpful in identifying harvesters.

Adding a jQuery MP3 Player in to eZ publish

I’ve been wanting to add a cross-browser audio player into a site for a while and I finally found a few minutes to find a solution and apply it.

A quick Google found the link above, which includes good demos and examples.

Files:

http://www.sean-o.com/files/singlemp3player.zip
http://www.sean-o.com/jquery/jmp3/jquery.jmp3.js

Download the files and place them in the design/site/javascript/mp3 directory, where site is the name of the siteaccess. Unzip the zip file.

Edit jquery.jmp3.js and ensure the path names match. The site will probably have to change.


var playerpath = "/design/site/javascript/mp3/";  

Update design.ini.append.php to add the jQuery MP3 code in.

settings/siteaccess/site/design.ini.append.php

[JavaScriptSettings]
JavaScriptList[]=mp3/jquery.jmp3.js

I updated design/site/override/templates/page_layout.tpl to use jQuery from the jQuery CDN.


<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.1.min.js"></script>

I also added the player load code directly into page_layout.tpl, since it was compact. A better approach is probably to add it in as a footer script using the admin interface.

<script type="text/javascript">
$(document).ready(function(){
$(".mp3").jmp3({
/*backcolor: "000000",
forecolor: "22ff22",*/
width: 400,
showdownload: "false",
showfilename: "false"
});
});
</script>

Finally, I override the line/file template, testing to see if the filename ended in .mp3. If the file is an .mp3, the player code is added. In hindsight, a more graceful solution would be to create a custom class for .mp3s, but this works fine.

design/site/override/templates/line_file.tpl

{def $attr=$node.data_map.file}
        {def $fileurl=concat( 'content/download/', $attr.contentobject_id, '/', $attr.id,'/version/', $attr.version , '/file/', $attr.content.original_filename|urlencode )}
        {if $fileurl|ends_with('.mp3')}<span class="mp3">{$fileurl|ezurl('no','full')}</span>{/if}
        {undef $attr}{undef $fileurl}

Many thanks to ’sean-o’ - see the link above.

I tested it on Windows and CentOS, with FireFox 3+, it works really nicely.

As a side note, while working on this, I needed to add the http:// to the URL, and it could not be encapsulated in double quotes, since the name is not assigned in an href or src attribute. eZ has two nice optional parameters for the ezurl function, the first indicating what type of quotes to use (in this case none), and whether to create a full URL or relative (in this case full).

Label with Every Font - ImageMagick

The goal of this adventure was to find the font that looked the best on a Massachusetts license plate, using ImageMagick.

I got the list of fonts using -list type fonts. This was run on two servers with different versions of ImageMagick, so there are two different ways to get the font list. Pick the one that works for you, or make your own.

The license plate blank came from R.T’s Blank Plates.

# This isn't worth automating, you will need to edit the font_list to strip out extra lines
#convert -list type fonts | cut -f1 -d ' ' | sort | uniq > font_list
# If the above won't work, try the next line
#convert -list font | grep 'Font:' | cut -f 2 -d ':' | tr -d ' ' > font_list
for f in $(cat font_list); do
echo $f
convert  ma1987.jpg -compose srcOver -gravity center \( -background transparent -fill "#7c2128" -strokewidth 1 -stroke "#777777" -font "$f" -pointsize "72" label:TAGLNZ -resize 230x -trim -sharpen 0x1.0 \) +composite MA-$f.png
done

This is one of the 270+ images that were created:

MA - Helvetica-Narrow

This is a good example of centering a label. The command line begins with the convert command, followed by the blank plate. ‘compose srcOver’ and ‘gravity center’ position the image labeled in parenthesis over the plate, and ‘+composite’ assembles the image.

Many thanks to the ImageMagick examples.

You can create your own license plate avatar at taglinez.com.

Quick Sprite Builder

Sprites allow you to combine many images into a single file, reducing both the number of requests and bandwidth required to deliver pages.

I had 51 images, each was about 10K, so the total was about 510K.

These images had dimensions of about 250px width and 125px height.

I wanted to combine them all into a single image, and generate the CSS to compute the offsets into the sprite.


#!/bin/bash

# Remove the prior appended image
rm appended.jpg

# Create a list of all the original jpg files
ls *.jpg > jpg_files

# Resize all the images to ensure they have the same height and width
for f in $(cat jpg_files); do
        convert "$f" -resize 250x125! +repage "$f";
done

# Break the list into rows of 10 images
split -l 10 jpg_files jpg_row.

# Generate the ImageMagick command to append the images into rows 
c=convert
for f in $(ls jpg_row.*); do 
        h=`cat "$f" | tr '\n' ' '`
        c="$c"' ( '"$h"' +append ) '
done
# Combine the rows into the appended image, reduce the quality to save space
c="$c"' -background transparent -append -quality 70  appended.jpg'
`$c`

echo '.tag{height:125px;width:250px;overflow:hidden;background-color:transparent;background-image:url("appended.jpg");}' > ap.css

# Generate the CSS
r=0
for f in $(ls jpg_row.*); do 
        c=0
        for g in $(cut -f 1 -d '.' "$f"); do
                echo ."$g"'{background-position:-'$((c*250))'px -'$((r*125))'px;}' >> ap.css
                c=$((c+1))
        done
        r=$((r+1))
done

The final image was about 260K, still large, but the quality is good. Compressed for transfer, this image will serve well.

This code isn’t generalized, if you would like to use it, you’ll need to adjust the image dimensions and the number used to calculate the offsets.

XML Fed Form Interface

This is a demonstration of how you can use XML to feed PHP to generate a form. It is helpful when a flexible form interface is needed. This example includes the name of the field, the length, a regex validation string, default value, label for the input, whether it is required or not, and error text. It could be extended have multilingual validation and error text.

<?xml version="1.0" encoding="utf-8" ?>
<interface>
        <name>Works</name>
        <fields>
                <field>
                        <name>URL</name>
                        <length>255</length>
                        <validation>[\w\.\-]{2,255}</validation>
                        <default>domain.com</default>
                        <label>URL</label>
                        <value>url.com</value>
                        <required>true</required>
                        <errortext>Letters, numbers, periods and dashes only</errortext>
                </field>
                <field>
                        <name>id</name>
                        <length>11</length>
                        <validation>[\d]{1,11}</validation>
                        <default>1</default>
                        <label>Id</label>
                        <required>true</required>
                        <errortext>Ids must be all digits</errortext>
                </field>
        </fields>
</interface>

This is the PHP that reads the XML. It uses SimpleXML, which is really nice.

<?php echo '<?xml version="1.0" encoding="utf-8" ?>' ?>
<?php
$xml=file_get_contents('bw.xml');
$xmldata = new SimpleXMLElement($xml);
$bValid=true;
/* Validate the submitted data */
if (isset($_POST['submit']))
{
        $bValid=true;
        foreach ($xmldata->fields->field as $f)
                if (isset($_POST["{$f->name}"]))
                {
                        $f->value=$_POST["{$f->name}"];
                        if (!preg_match('/^'.$f->validation.'$/',$_POST["{$f->name}"]))
                        {
                                $f->invalid=(bool)true;
                                $bValid=false;
                        }
                }
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XML Form</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
label
{
font-weight:bolder;
}
input,label
{
display:block;
}
.invalid
{
color:#f00;
}
</style>
</head>
<body>
<h1>XML Form Sourcing Demo</h1>
<hr />
<h2>Generated Inputs</h2>
<!-- 
Generates the form from the XML data.  Note the use of the invalid flag for highlighting, and the display of
errortext if appropriate.
-->  
<form action="#" method="post">
<?php foreach ($xmldata->fields->field as $f) : ?>
<label <?php if (isset($f->invalid)) echo 'class="invalid"' ?> for="<?php echo $f->name?>"><?php echo (($f->required==
'true')?'*':'').$f->label ?>
<?php if (isset($f->invalid)) echo ' '.$f->errortext; ?>
<input name="<?php echo $f->name ?>" id="<?php echo $f->name ?>"
        maxlength="<?php echo $f->length ?>"
        value="<?php echo (isset($f->value)?$f->value:$f->default) ?>" />
</label>
<?php endforeach ?>
<br />
<input name="submit" type="submit" />
</form>
<h2>Raw XML Data</h2>
<!-- Display the raw XML data, for debugging/development -->
<blockquote><?php echo nl2br(htmlentities(file_get_contents('bw.xml'))) ?></blockquote>
<h2>Parsed XML</h2>
<!-- Display how SimpleXML parsed the XML, again for debugging/development -->
<?php
echo '<pre>';
var_dump($xmldata);
echo '</pre>';
?>
<h2>Updated XML (if valid)</h2>
<!-- Show how the XML was updated, if it was valid -->
<?php
if ($bValid)
        echo '<pre>'.nl2br(htmlentities($xmldata->asXML())).'</pre>';
?>
</body>
</html>

This is well-suited for applications which must use connection data into a variety of external interfaces. In this case, the data can be presented, entered, validated, and stored, then used later by a different process.