Category: "EzPlatform / Ibexa"

mod_proxy_ajp declining URL

Many hours of searching and suffering were spent trying to resolve this ...

Apache-Error: [file "mod_proxy_ajp.c"] [line 743] [level 7] AH00894: declining URL fcgi://localhost/var/www/html/site/public/index.php

This is a Symfony application (ibexa DXP, formerly eZ Platform, previously eZ Publish), CentOS 8 server, with PHP 7.4, mod_security, selinux enabled, etc.

The error was thrown on the graphql requests to support the sub-items display of the admin interface.

The root cause of the issue was an application error.

The message from Symfony

[2022-01-05T18:34:58.709826+00:00] request.CRITICAL: Uncaught PHP Exception Overblog\GraphQLBundle\Resolver\UnresolvableException: "Could not found type with alias "RepositoryLanguage". Do you forget to define it?" at /var/www/html/site/vendor/overblog/graphql-bundle/src/Resolver/TypeResolver.php line 72 {"exception":"[object] (Overblog\\GraphQLBundle\\Resolver\\UnresolvableException(code: 0): Could not found type with alias \"RepositoryLanguage\". Do you forget to define it? at /var/www/html/site/vendor/overblog/graphql-bundle/src/Resolver/TypeResolver.php:72)"} []

This also took me a long time to unravel - about an hour ... because I haven't worked with eZ in a while

Solution was to copy all these files https://github.com/bgamrat/improved-journey/tree/main/config/graphql/types/ezplatform into the config.

Next, it was time to make this blog post with the goal of helping you!

I changed the username for security, to a word I rarely use. So of course I forgot it. As well as the password. Tried to email a password reset, but that failed too ... selinux, remember?

setsebool -P httpd_can_sendmail 1

I also tried to reset the password at the database level, but that looked like more effort.

So - it was a grand adventure, the installation works and I can go do other things.

Using wkhtmltopdf to generate a PDF from eZ Platform

I wanted to produce a polished PDF of restricted content managed by https://ezplatform.com/ with the least amount of effort possible and I wanted an approach that would allow me to run a single command on the command line.

My first approach was to try to use a browser's print to PDF feature, but I wasn't happy with the results. So I tried https://wkhtmltopdf.org/,

After tinkering with various roles/permissions and firewall configurations with eZ Platform and Symfony I chose to create a PDF user which was allowed to log in and view only the target content. I used curl to log in, extracted the eZ session id cookie and passed it to wkhtmltopdf for rendering.


#!/bin/bash
if [ "$#" -ne 1 ]; then
    echo "Usage: $0.sh url"
    exit;
fi;
USER=pdfuser
PASS=somepassword

URL=$1;
PDF=`echo $1 | sed "s/.*\/\([^\/]\+\)$/\1/"`
FOOTER_LEFT=${PDF^^}
LOGIN_URL=`echo $1 | sed "s/^\(https\?:\/\/[^\/]\+\/\).*$/\1login/"`
CSRF_TOKEN=`curl -s -X GET --cookie-jar cookie "$LOGIN_URL" | grep -o "name=\"_csrf_token\" value=\"\([^\"]\+\)\"" | sed "s/.*value=\"\([^\"]\+\)\"/\1/"`
LOGIN_DATA="_username=$USER&_password=$PASS&_csrf_token=$CSRF_TOKEN"
curl -L -s -b cookie --cookie-jar cookie -d "$LOGIN_DATA" "$LOGIN_URL"_check > /dev/null
COOKIE=`grep -o "\(eZSESS.*\)$" cookie | sed "s/\s\+/ /g"`
wkhtmltopdf --cookie $COOKIE --print-media-type --margin-left .5in --margin-right .5in --margin-top .5in --margin-bottom .5in "$URL" --footer-left "$FOOTER_LEFT" --footer-center 'Page [page] of [topage]' --footer-font-name 'Open Sans' --footer-font-size 8 --footer-right 'Updated [date]' "$PDF.pdf"

Thanks to: https://serverfault.com/a/306360/311430 for help with the cookies in the Apache log

eZ Publish - Adding Bootstrap Glyphicons

If you are using Bootstrap with eZ Publish, you can add a custom tag to include glyphicons which will allow editors to add the icons into their content.

This is a simple implementation, it allows the user to enter the name of the icon they would like to use.

content.ini.append.php

<?php /* ini charset="utf-8"

[CustomTagSettings]
AvailableCustomTags[]=glyphicon
IsInline[glyphicon]=true

[glyphicon]
CustomAttributes[]
CustomAttributes[]=name

*/ ?>

The template HTML must match the Bootstrap version in use.

design/site/templates/content/datatype/view/ezxmltags/glyphicon.tpl

<!-- Choose the HTML for the tag based on the version of Bootstrap you are using -->
<span class="glyphicon glyphicon-{$name}"></span>

<!-- or -->

<i class="icon-{$name}"></i>

eZ Publish - Object Relation Attributes - Reckless Cleanup

This is NOT A FIX for the code, but if you are getting confusing results for queries due to relationships between object relation attributes which were deleted from content classes, you may use this query:

Backup your database first

This is not for the faint of heart

There are no warranties or other guarantees - use this at your own risk.

DELETE FROM ezcontentobject_link WHERE contentclassattribute_id != 0 AND NOT EXISTS (SELECT * FROM ezcontentclass_attribute WHERE ezcontentclass_attribute.id = ezcontentobject_link.contentclassattribute_id);

eZ 4.x Custom User Group Assignment Workflow

This is a simple workflow event that will extract a member type attribute (single select) and use it to assign the member into a group on register.

It catches not only self-registration, but updates made through the admin interface.

<?php
class HPMemberRegisterType extends eZWorkflowEventType
{
	const WORKFLOW_TYPE_STRING = 'hpmemberregister';

	public function __construct() 
	{
		parent::__construct( HPMemberRegisterType::WORKFLOW_TYPE_STRING, 'HP Member Register' );
	}
	
	public function execute ( $process, $event )
	{
		$parameters = $process->attribute( 'parameter_list' );
		
		$ini = eZINI::instance( 'hpmember.ini' );

		$objectID = $parameters['object_id']; 
		$object = eZContentObject::fetch( $objectID );
		$nodeID = $object->attribute( 'main_node_id' );
		$node = eZContentObjectTreeNode::fetch( $nodeID );

		if ( $object->contentClassIdentifier() === 'member' ) {

			$dataMap = $object->dataMap();
			$memberTypeValue = $dataMap[ 'member_type' ]->content();
			$contentClass = $object->contentClass();
			$memberTypes = $contentClass->fetchAttributeByIdentifier( 'member_type' )->content();
			$memberType = $memberTypes['options'][$memberTypeValue[0]]['name'];
			$memberGroup = $ini->variable( 'MemberGroup', $memberType );
			if ( $memberGroup !== null ) 
			{
				$node->setAttribute ( 'parent_node_id', $memberGroup );
				$node->store();
			}
		}

		return eZWorkflowType::STATUS_ACCEPTED;
	}
}
eZWorkflowEventType::registerEventType( HPMemberRegisterType::WORKFLOW_TYPE_STRING, 'hpmemberregistertype' );

.ini file:

<?php /* #?ini charset="utf-8"?

# The node id members with that type should be placed in
[MemberGroup]
Contractor=60
Homeowner=61
Lender=62
Realtor=63

*/ ?>

You can place your nodes where you like. Be sure the names under [MemberGroup] are identical to the options in the selection attribute added to the class used for user registration. This code uses a custom Member class to distinguish eZ Users from site members.

1 3 4 5