Skip to content

Propel, the PropelOnDemandFormatter, self loaded runtime properties and your special reload data if needed usecase- howto

Propel column representation offering the option to add some business logic inside. We are making this from time to time by enriching the existing object with more data, but only when a method is called explicit.


class MyTable extends BaseMyTable
{
    /** @var null|\My\Enriched\MyTable\Data */
    protected $enrichedData;

/**
 * @return null|\My\Enriched\MyTable\Data
 */
public function getEnrichedData()
{
    //prevent reloading enriched data if this method is called more than once
    if ($this->noEnrichedDataYetLoaded()) {
        //do something heavy data lifting
        $this->enrichedData = $this->tryToLoadEnrichedData();
    }

    return $this->enrichedData;
}

/**
 * @return bool
 */
private function noEnrichedDataYetLoaded()
{
    return (is_null($this->enrichedData));
}

}

If you would use the corrosponding MyTableQuery object in combination with a PropelOnDemandFormatter and iterating over an collection after calling find(), you would get the same enriched data for different MyTable objects.
Why? Because the PropelOnDemandFormatter does a smart thing by reusing the on MyTable object and "just" updating the properties.
Following is a workaround I am using to fix this (totally right) behaviour. Anyways, be caution if you do things like that. This should not be your regular way of doing it.


class MyTable extends BaseMyTable
{
    /** @var null|\My\Enriched\MyTable\Data */
    protected $enrichedData;

/** @var int */
protected $myId;

/**
 * @return null|\My\Enriched\MyTable\Data
 */
public function getEnrichedData()
{
    //prevent reloading enriched data if this method is called more than once
    if ($this->noEnrichedDataYetLoaded()) {
        //do something heavy data lifting
        $this->enrichedData = $this->tryToLoadEnrichedData();
        $this->myId         = $this->getId();
    }

    return $this->enrichedData;
}

/**
 * @return bool
 */
private function noEnrichedDataYetLoaded()
{
    return (
        ($this->myId == $this->getId())
        && (is_null($this->enrichedData))
    );
}

}

Translate to de es fr it pt ja

Reminder of the Propel Bug 734 - update() with limit() and a workaround

Just because we ran into this issue again. There is known and serious bug in propel whenever you use "update()" in combination with "limit()".
Our workaround right now is to replace the code.


//this will update all entry with the content "bar" in the column "foo"
MyQuery::create()
    ->filterByFoo('bar')
    ->limit(100)
    ->update(
        array(
            'Foo' => 'baz'
        )
    );

//this will only update 100 rows $ids = (array) MyQuery::create() ->filterByFoo('bar') ->limit(100) ->select( array( 'Id' ) ) ->find();

MyQuery::create() ->filterById($ids) ->update( array( 'Foo' => 'baz' ) );

Translate to de es fr it pt ja

howto - php composer - File(/etc/pki/tls/certs) is not within the allowed path(s) - on arch linux

Since a few days (or weeks?), I discovered the following issue on one of my Arch Linux system.
Whenever I try to use PHP's composer, I got the following issue:


[ErrorException]
is_dir(): open_basedir restriction in effect. File(/etc/pki/tls/certs) is not within the allowed path(s): (/srv/http/ [...]

Well, it didn't hurt that much since I am using (like every cool webkiddy is doing) docker or vagrant for my development. But this time, I needed to solve it since it is a customer edge case - so I solved it.
The how to I will show you is not the perfect way. I had two things in mind, try to minimize the place I have to adapt the php.ini. And try to keep the system as normal as possible. Until now, I can not estimate the security holes I opened with this setting. I will let you know if this how to turns out to be a "don't try this at home" thing.

So, what have I done?
First of all, I asked curl to tell me where it is looking for certificates by executing:


curl-config --ca

output: /etc/ssl/certs/ca-certificates.crt


After that I had a look what this path is:

ls -halt /etc/ssl/certs/ca-certificates.crt

output: [...] /etc/ssl/certs/ca-certificates.crt -> ../../ca-certificates/extracted/tls-ca-bundle.pem


So, with that knowledge it turned out that the following steps are reflecting my requirements mention above.

sudo mkdir -p /etc/pki/tls/certs
sudo ln -s /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-certificates.crt
sudo vi /etc/php/php.ini

add following lines to "open_basedir" configuration section

:/etc/pki/tls/certs:/etc/ssl/certs


And that is it, composer should now be back in business.

Translate to de es fr it pt ja

PHP DateInterval::__construct(): Unknown or bad format - trouble with ISO 8601 Date Format

To keep it short, you code is failing because of an message like:


DateInterval::__construct(): Unknown or bad format (P0Y2M7DT-1H7M14S) 
Why? Well it is obvious if your eyes are fresh, otherwise well hidden.
The bad thing is the "-" between "T" and "1". Cover your string by let it run through str_replace('-', '', $dateIntervalAsString) and you are a step closer to pretty safe code.
How can this happen?
First of all, by strange data and secondly by trying to solve the date format on your own. Really, old code is your enemy at this point.

For the sake of input and output, here are some important links:

Translate to de es fr it pt ja

Creating an Email with a return path (needed for bounce management) that is not overwritten by the SMTP by using the PHP Zendframework 2

This time, my task was to create an email in an zend framework 2 environment.
The complicated part was the fact, that I wanted to set the "Return-Path". I did it this way $headers->addHeader('Return-Path', ''); but it always got overwritten.
After a while and a chat with an other technical guy and some readings of some SMTP configuration files and specifications, we found the solution. You have to envelope the mail and the zend framework has a class for this. Following is a generic and general solution for this problem.


<?php
[email protected]: https://artodeto.bazzline.net/archives/835-Creating-an-Email-with-a-return-path-needed-for-bounce-management-that-is-not-overwritten-by-the-SMTP-by-using-the-PHP-Zendframework-2.html
//full qualified class names since I wanted to keep the code snippet
//  as short as possible

//begin of parameters
$body               = new \Zend\Mime\Message();
$bounceEmailAddress = '<unique bounce email address>';
$encoding           = 'UTF-8';
$envelope           = new \Zend\Mail\Transport\Envelope();
$fromEmailAddress   = '<[email protected]>';
$fromName           = '<your name>';
$htmlContent        = '<p>html content</p>';
$message            = new \Zend\Mail\Message();
$options            = new \Zend\Mail\Transport\SmtpOptions(
    array(
        'connection_class'  => '<login>',
        'connection_config' => array(
            'password'  => '<password>',
            'username'  => '<user name>'
        ),
        'host'              => '<smtp host>',
        'name'              => '<smtp name>'
    )
);
$subject            = '<subject>';
$textContent        = 'text content';
$toEmailAddress     = '<[email protected]>';
$toName             = '<user name>';
$transporter        = new \Zend\Mail\Transport\Smtp();
//end of parameters

//begin of text content creation
$textPart = new \Zend\Mime\Part($textContent);

$textPart->setCharset($encoding );
$textPart->setType(\Zend\Mime\Mime::TYPE_TEXT);

$body->addPart($textPart);
//end of text content creation

//begin of html content creation
$htmlPart = new \Zend\Mime\Part($htmlContent);

$htmlPart->setCharset($encoding );
$htmlPart->setType(\Zend\Mime\Mime::TYPE_HTML);

$body->addPart($htmlPart);
//end of html content creation

//begin of building and sending the mail
$envelope->setFrom($bounceEmailAddress);
$envelope->setTo($toEmailAddress);

$message->setBody($body);
$message->addFrom($fromEmailAddress, $fromName);
$message->addReplyTo($bounceEmailAddress);
$message->setSubject($subject);
$message->addTo($toEmailAddress, $toName ;
$message->setEncoding($encoding );

$transporter->setEnvelope($envelope);
$transporter->setOptions($options);
$transporter->send($message);
//end of building and sending the mail
Hopefully, this will speed up your problem solving. It took me longer than wished and expected to fix this issue.
It was strange to do an header dump and seeing the correct "Return-Path", because the smtp is rewriting it on its own.

Following some links I used to fix this problem:

By the way and just to put another simple example into the web. Following an easy way to handle bounce emails (return path) via sendmail.


$bounceEmailAddress = '<unique bounce email address>';
$encoding           = 'UTF-8';
$fromEmailAddress   = '<[email protected]>';
$fromName           = '<your name>';
$subject            = '<subject>';
$textContent        = 'text content';
$toEmailAddress     = '<[email protected]>';
$toName             = '<user name>';

$header = 'From: ' . $fromEmailAddress . ' <' . $fromEmailAddress . '>' . "\r\n"; iniset('sendmailfrom', $fromEmailAddress); mail($toEmailAddress, $subject, $textContent, $header, '-f' . $bounceEmailAddress); //-f is the magic trigger to set an return path

Translate to de es fr it pt ja

howto - add type hinting to phpstorms generated setter method

A colleague of me forwarded me this super cool solution/template to remove one of the little annoying corners of the great PHPStorm IDE (beside the sad fact, that it is closed source software of course).
The template is fixing the problem with the generated setter methods and the missing type hinting.

Open PhpStorm's Preferences and "File and Code Templates" menu, under the "Code" tab there's an option called "PHP Setter Method". Modify it to look like this:
#set($typeHintText = "$TYPE_HINT ")

First we check against a blacklist of primitive and other common types used in documentation.

set($nonTypeHintableTypes = ["", "string", "int", "mixed", "number", "void", "object", "real", "double", "float", "resource", "null", "bool", "boolean"])

foreach($nonTypeHintableType in $nonTypeHintableTypes)

#if ($nonTypeHintableType == $TYPE_HINT)
    #set($typeHintText = "")
#end

end

Make sure the type hint actually looks like a legal php class name(permitting namespaces too) for future proofing reasons.

This is important because PSR-5 is coming soon, and will allow documentation of types with syntax like SplStack

if (!$TYPEHINT.matches('^((\)?[a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+)+$'))

#set($typeHintText = "")

end

Next, we check if this is using the array syntax like "MyClass[]", and type hint it as a plain array

if ($TYPE_HINT.endsWith("[]"))

#set($typeHintText = "array ")

end

/** * @param ${TYPEHINT} $${PARAMNAME} */ public ${STATIC} function set${NAME}($typeHintText$${PARAM_NAME}) {

if (${STATIC} == "static")

self::$${FIELD_NAME} = $${PARAM_NAME};

else

$this->${FIELD_NAME} = $${PARAM_NAME};

end

}


source
File Template Variables

Translate to de es fr it pt ja

gosh, why is my vendor directory consuming so much diskspace?

"Saving disk space on your composer projects" was a headline for an older entry I made.
I used this project and figured out it has a lot of bugs because of its "outdateness". Thats why I spend some time to create a build script, build a new "compify.phar" and created a pull request to it. Sadly, no response or action has been done by carlos (also no response on any e-mail).
I did the pull request on 28.07.2015, meaning a lot of water is gone down the river since then.
After waiting and waiting, I gave up and simple added my created "compify.phar" in a project called php project maintenance. As given by the name, this project has to goal to easy up maintenance for php projects ;-).
The, currently, best script inside is updateallrepositories which simple tries to find all git repositories from your current working directory. Inside each directory, it is doing some git stuff and also - since today - using compify to clean up the vendor diskspace. If you want to automate that kind of process, feel free to use it and pull some requests if there is something that can be optimized.

Translate to de es fr it pt ja

CreateEntity Propel Behavior released in version 1.0.0

I am happy to announce the release of Version 1.0.0 of the CreateEntity Behavior for Propel.

Why?

  • no new in your code anymore
  • eases up writing test code (createEntity can be mocked)
Translate to de es fr it pt ja

php pdo library that adds array quoting as feature

I was searching for a php library that extends PDO in that way, that I don't have to rewrite the "quote each entry in an array on its own by calling "$pdo->quote($value)" again and a gain.
Thanks to the community, there is one small library taking care about this problem - Aura.Sql.
I'm tired today but I will give it a try tomorrow. It is looking very usefull.

Translate to de es fr it pt ja

Saving disk space on your composer projects

Have you ever did a "du -sh" on your vendor folder and became shocked because of the size?
As example, if you require the zend framework 2 in your project, you have to download and store over 170 MB in your disk. Hopefully, you don't think this is the size of the framework.
And you are right, over 150 MB of the size is inside the ".git" folder. That is "nice to know" information if you are a zend framework 2 developer, but if you simple use it, you don't need it.
Thanks to carlos buenos vinos, all you need to do is to download a tool called compify. Once setted up on your machine, you only have to change into your project root and execute "compify crush vendor/".
You can automate that call by binding it with the "composer update" call, either via shell alias, shell script, ant target or phing target (or are you using maven for a php project?).

Translate to de es fr it pt ja

zend framework 2 - translation on steroids - some thoughts

The following lines are loud thoughts so far. I will give it a try and implement a fitting module for that. But so far, it is really just an idea.

You started your zend framework 2 translation by using the official translation guide for zend framework 2 and it was running fine with some words.
But then, you started working agile, using git flow and doing this by using multiple branches. It turned out that you will get a lot of merge conflicts (also on git) with your translation files if something had changed on your develop branch and on your feature branch. This results in high maintenance costs.

So what to do?
Here is my basic idea. Decouple the translation file from your code.

  • First of all, you want to shift from file based to database based translation.
  • After that, you reduce the usage of the database and add caching

Shift from file based to database based translation

  • Create a database with the name like "translation"
  • Inside this database, create a table called "keys" with the columns "id", "keyname" (or "name") and "createdat"
  • Inside this database, create as many "language" tables as you want
  • Each "language" table has the following columns "id", "keyid", "keyvalue" (or "value") and "created_at"
  • After that, create a basic import that inserts all names in the table "keys" and all values in the fitting "language" table
  • Next, you have to create an "translation adminstration" frontend to maintain the existing "translation keys" with its fitting "translation values" according to the right language.
  • Finally, you have to overwrite the existing view helper with your own, database driven, one

Reduce the usage of the database and add caching

Translate to de es fr it pt ja

Convert VCF File into a CSV File

I needed to convert a VCF file into a CSV file by fetching the important and readable informations.
Thanks to the bazzline component it was a quick win/no brainer. You can find the result here. It is written under GPL-3 License.

How to use it?

  • open a terminal / command line
  • git clone https://github.com/stevleibelt/incubator
  • cd incubator/general/vcftocsv_converter
  • ./converter
Translate to de es fr it pt ja

zend framework 2.4 "Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for ApplicationConfig"

We had some controller tests in our test cases and the following error was thrown, after we updated to zend framework 2.4.


Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for ApplicationConfig

/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:555 /vendor/zendframework/zendframework/library/Zend/Mvc/Service/ModuleManagerFactory.php:41 /vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:939 /vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:1097 /vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:638 /vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:598 /vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:530 /vendor/zendframework/zendframework/library/Zend/Mvc/Application.php:253 /vendor/zendframework/zendframework/library/Zend/Test/PHPUnit/Controller/AbstractControllerTestCase.php:164 /vendor/zendframework/zendframework/library/Zend/Test/PHPUnit/Controller/AbstractControllerTestCase.php:73 //MyControllerTest.php:124

"MyControllerTest" extends "Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase". What we did to solve the problem was adding the following lines of code in our "setUp" method.

$applicationConfigurationPath = DIR . strrepeat('/..', ) . '/config/application.config.php';
if (!isfile($applicationConfigurationPath)) {
    $message = 'application configuration needed and not found in path "' . $applicationConfigurationPath . '"';

$this->fail($message);

} $applicationConfiguration = require $applicationConfigurationPath; unset($applicationConfiguration['modulelisteneroptions']['configglobpaths']); $applicationConfiguration['modules'] = array();

$this->setApplicationConfig($applicationConfiguration);


Thats it, hope it helps.

Translate to de es fr it pt ja

New versions of the zend framework 2 console helper family available now

I happy to announce the release of 1.1.0 of bazzlines zend framework 2 console helper (debian backport) module for php as well as the release of 1.1.0 of bazzlines zend framework 2 console helpermodule for php.
Important changes are:

  • added AbstractConsoleControllerFactory
Translate to de es fr it pt ja

Updated Zend Framework 2 Modules because of the locator generator version 2.0.0 release

I announced already, version 2.0.0 of the "locator generator" is out.
Because of that, I am also happy to announce the release of 1.4.1 from the zend framework 2 "locator generator" module.
Furthermore, the debian 6/PHP 5.3 backport got the release of version 1.3.0.
And finally, and because of the fact that zend framework 2.5.* is dropping support for PHP 5.4, the new debian 7/PHP 5.4 got the release of version 1.7.0.
Major changes in all releases is the dependency update to the new locator generator version.

You want to have a quick look and tryout without any hassle? Try the zf demo environment available in three flavors, cutting edge, debian 7/PHP 5.4 backport and debian 6/PHP 5.3 backport.

Translate to de es fr it pt ja

version 2.0.0 of php locator generator component released

I happy to announce the release of 2.0.0 of bazzlines locator generator component for php. Important changes are:

  • Generator.php now throws "InvalidArgumentException" instead of "RuntimeException
  • Generator now tries to create the provided directory if it does not exists
  • fixed issue 2
  • fixed issue 4
  • fixed issue 5
  • implement usage of phpcomponentcliarguments
  • implement usage of phpcomponentcommand
  • fixed broken entry of "bin" in composer.json
  • renamed "bin/generaltelocator" to "bin/netbazzlinegeneratelocator"
  • renamed "bin/generateLocator.php" to "bin/generatelocator"
  • renamed "example/[..]/run.php" to "example/[...]/run"
  • fixed issue 3
  • updated dependencies
Translate to de es fr it pt ja

php SplFileObject and the difference between fgetcsv and current

I had to investigate a bug and figured out a strange behavior in the SplFileObject implementation of php. I know, some of you would add "again", but this does not matter.
To illustrate this problem, I created a little example file. If you run it, you get the following output:


generating content.
..........
writing content.
..........
using fgetcsv and writing key 13 times.
0 0 1 2 3 4 5 6 7 8 9 10 10 
using current and writing key 13 times.
0 0 0 0 0 0 0 0 0 0 0 0 0

As you can see, if you use "fgetcsv", the current key is move to the next step.
If you use "current", the current key won't get updated (which is most likely what you want).
You can easily set the csv delimiter etc. by using setCsvControl()".

Categories: coding
Defined tags for this entry: , , , , , ,
Vote for articles fresher than 7 days!
Derzeitige Beurteilung: 4.50 of 5, 2 Stimme(n) 781 hits

version 1.0.0 of php component cli argument released

I am happy to annoucen the release of 1.0.0 of bazzlines cli argument component for php.
Benefits

  • easy up handling of following kinds of arguments
    • flags (command -f|--force)
    • lists (command --foobar=foo | command -f=foo)
    • values values (command )

Example
A simple call to the shipped "run.php" with the following arguments:

php run.php --foo bar --foobar=foo --foobar="bar" -f="foo" -f=bar -b foobar foo -flag
Generates the following output:

arguments provided:
    --foo
    bar
    --foobar=foo
    --foobar=bar
    -f=foo
    -f=bar
    -b
    foobar
    foo
    -flag
flags provided:
    foo
    b
    f
    l
    a
    g
lists provided:
    foobar
        foo
        bar
    f
        foo
        bar
values provided:
    bar
    foobar
    foo

Translate to de es fr it pt ja

version 1.1.0 of php component requirement released

I happy to announce the release of 1.1.0 of bazzlines requirement component for php. Important changes are:

  • added example WithDisabledCondition
  • added example WithDisabledItem
  • added getConditions() method to RequirementInterface - this easies up disabling single conditions or single items (by using condition->getItems())
  • added migration howto
  • added version eye and scrutinizer coverage
  • covered AbstractItem and AbstractCondition with unit test
  • created AbstractItem that implements ItemInterface
  • created IsDisabledInterface
  • created ItemInterface
  • created TestCase that is extended by all phpunit tests
  • implemented IsDisabledInterface to AbstractCondition
  • implemented IsDisabledInterface to Requirement
  • refactored ConditionInterface, addItem now only accepts ItemInterface instead of IsMetInterface
  • refactored Condition::getItems() - now returns plain php array
  • renamed ConditionAbstract to AbstractCondition
  • renamed and updated previous WithShutdown example to WithDisabledRequirement
  • updated dependencies
Translate to de es fr it pt ja

php - zfcampus/zf-rest how to | tutorial

Assuming you are using the Zend Framework 2 and want to implement a REST endpoint in a quick and fully functional way.
ZF-Rest is, more or less, the official rest module for zf2. But, the documentation is not available - nor planned right now. Thats why I this blog entry will boost your knowledge and speed up the time until you have finished your first zf2 rest endpoint.

Installation and Setup

add the following line to you composer.json

"zfcampus/zf-rest": "1.0.3"

You need to add the following entries in your to "config/autload/application.config".


<?php

return array( 'modules' => array( //your modules 'ZF\ApiProblem', 'ZF\ContentNegotiation', 'ZF\Hal', 'ZF\MvcAuth', 'ZF\OAuth2', 'ZF\Rest' );

Minimal Configuration (module.config.php)

array key "zf-rest"


//MyRestController is a virtual Controller 
'My\Module\Namespace\MyRestController' => array(
    //mandatory - available are GET, POST, PUT, PATCH, DELETE
    'collectionhttpmethods'       => array(
        'GET'
    ),
    //mandatory - available are GET, POST, PUT, PATCH, DELETE
    'entityhttpmethods'           => array(
        'GET'
    ),
    //virtual name - its the name the collection entries are getting in the HAL-repesentation
    'collectionname'               => 'items',
    'routename'                    => 'myrestroutename',
    'routeidentifiername'         => 'id',
    //this is the only file you really need to code/implement
    'listener'                      => 'My\Module\Namespace\MyListener'
),

array key "router/routes"


'myrestroutename' => array(
    'type' => 'Zend\Mvc\Router\Http\Segment',
    'options' => array(
        'route' => '/my/rest/endpoint/[/:id]',
        'defaults' => array(
            //MyRestController is a virtual Controller
            //The name is needed to map the module configuration to the endpoint
            'controller' => 'My\Module\Namespace\MyRestController'
        )
    ),

Optional Configuration Values

Based on the source code from RestControllerFactory.php, following configuration keys are optional (mention as mandatory in the current README.md).

  • resourceidentifiers
  • identifier
  • controllerclass
  • entityclass
  • collectionclass
Translate to de es fr it pt ja

version 1.0.1 of process pipeline component for php released

I happy to announce the release of 1.0.1 of bazzlines process pipeline component for php. Important changes are:

  • removed dependecy to apigen
  • add "StopExecutionException"
Translate to de es fr it pt ja

version 1.0.2 of zend framework 2 console helper (debian 6 backport) released

I happy to announce the release of 1.0.2 of bazzlines zend framework 2 console helper (debian backport) module for php. Important changes are:

  • removed dependency to apigen
  • updated dependencies
Translate to de es fr it pt ja