Overwrite Zend_Config and access parents nodes - zend-framework

I want to overwrite Zend_Config method __set($name, $value), but I have same problem.
$name - return current key of overwrite config value, eg:
$this->config->something->other->more = 'crazy variable'; // $name in __set() will return 'more'
Because every node in config is new Zend_Config() class.
So - how from overwritten __set() metod get access to the parents nodes names?
My application:
I must overwrite same config value in controller, but to have controll about the overwritting, and do not allow to overwrite other config variables, I want to specify in same other config variable, an tree-array of overwriting allowed config keys.

Zend_Config is read only unless you have set $allowModifications to true during construction.
From the Zend_Config_Ini::__constructor() docblock:-
/** The $options parameter may be provided as either a boolean or an array.
* If provided as a boolean, this sets the $allowModifications option of
* Zend_Config. If provided as an array, there are three configuration
* directives that may be set. For example:
*
* $options = array(
* 'allowModifications' => false,
* 'nestSeparator' => ':',
* 'skipExtends' => false,
* );
*/
public function __construct($filename, $section = null, $options = false)
This means that you would need to do something like this:-
$inifile = APPLICATION_PATH . '/configs/application.ini';
$section = 'production';
$allowModifications = true;
$config = new Zend_Config_ini($inifile, $section, $allowModifications);
$config->resources->db->params->username = 'test';
var_dump($config->resources->db->params->username);
Result
string 'test' (length=4)
In response to comment
In that case you can simply extend Zend_Config_Ini and override the __construct() and __set() methods like this:-
class Application_Model_Config extends Zend_Config_Ini
{
private $allowed = array();
public function __construct($filename, $section = null, $options = false) {
$this->allowed = array(
'list',
'of',
'allowed',
'variables'
);
parent::__construct($filename, $section, $options);
}
public function __set($name, $value) {
if(in_array($name, $this->allowed)){
$this->_allowModifications = true;
parent::__set($name, $value);
$this->setReadOnly();
} else { parent::__set($name, $value);} //will raise exception as expected.
}
}

Always there is another way :)
$arrSettings = $oConfig->toArray();
$arrSettings['params']['dbname'] = 'new_value';
$oConfig= new Zend_Config($arrSettings);

Related

How to extend date picker viewhelper of EXT:powermail?

I need to add a custom validator to the datepicker field. By default, this field comes without any validators.
I've already made the validator settings visible in the TCA of tx_powermail_domain_model_field and added my custom validator as usual.
Now I need the attributes data-parsley-customXXX and data-parsley-error-message added to the HTML input field which is usually done via the the viewhelper in ValidationDataAttributeViewHelper.php:
https://github.com/einpraegsam/powermail/blob/develop/Classes/ViewHelpers/Validation/ValidationDataAttributeViewHelper.php#L342
https://github.com/einpraegsam/powermail/blob/develop/Classes/ViewHelpers/Validation/ValidationDataAttributeViewHelper.php#L348
This is the code I need to extend:
https://github.com/einpraegsam/powermail/blob/develop/Classes/ViewHelpers/Validation/DatepickerDataAttributeViewHelper.php#L32
I found a solution for my problem. As suggested in the comment it's possible to extend the Viewhelper:
ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\In2code\Powermail\ViewHelpers\Validation\DatepickerDataAttributeViewHelper::class] = [
'className' => \Vendor\MyExt\Powermail\ViewHelpers\Validation\DatepickerDataAttributeViewHelper::class
];
myext/Classes/Powermail/ViewHelpers/Validation/DatepickerDataAttributeViewHelper.php
<?php
declare(strict_types=1);
namespace Vendor\MyExt\Powermail\ViewHelpers\Validation;
use In2code\Powermail\Domain\Model\Field;
use In2code\Powermail\Utility\LocalizationUtility;
class DatepickerDataAttributeViewHelper extends \In2code\Powermail\ViewHelpers\Validation\DatepickerDataAttributeViewHelper
{
/**
* Returns Data Attribute Array Datepicker settings (FE + BE)
*
* #return array for data attributes
*/
public function render(): array
{
/** #var Field $field */
$field = $this->arguments['field'];
$additionalAttributes = $this->arguments['additionalAttributes'];
$value = $this->arguments['value'];
$additionalAttributes['data-datepicker-force'] =
$this->settings['misc']['datepicker']['forceJavaScriptDatePicker'];
$additionalAttributes['data-datepicker-settings'] = $this->getDatepickerSettings($field);
$additionalAttributes['data-datepicker-months'] = $this->getMonthNames();
$additionalAttributes['data-datepicker-days'] = $this->getDayNames();
$additionalAttributes['data-datepicker-format'] = $this->getFormat($field);
if ($value) {
$additionalAttributes['data-date-value'] = $value;
}
if ($field->getValidation() && $this->isClientValidationEnabled()) {
$value = 1;
if ($field->getValidationConfiguration()) {
$value = $field->getValidationConfiguration();
}
$additionalAttributes['data-parsley-custom' . $field->getValidation()] = $value;
$additionalAttributes['data-parsley-error-message'] =
LocalizationUtility::translate('validationerror_validation.' . $field->getValidation());
}
$this->addMandatoryAttributes($additionalAttributes, $field);
return $additionalAttributes;
}
}

Slim 4 get all routes into a controller without $app

I need to get all registed routes to work with into a controller.
In slim 3 it was possible to get the router with
$router = $container->get('router');
$routes = $router->getRoutes();
With $app it is easy $routes = $app->getRouteCollector()->getRoutes();
Any ideas?
If you use PHP-DI you could add a container definition and inject the object via constructor injection.
Example:
<?php
// config/container.php
use Slim\App;
use Slim\Factory\AppFactory;
use Slim\Interfaces\RouteCollectorInterface;
// ...
return [
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
return AppFactory::create();
},
RouteCollectorInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getRouteCollector();
},
// ...
];
The action class:
<?php
namespace App\Action\Home;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Response;
use Slim\Http\ServerRequest;
use Slim\Interfaces\RouteCollectorInterface;
final class HomeAction
{
/**
* #var RouteCollectorInterface
*/
private $routeCollector;
public function __construct(RouteCollectorInterface $routeCollector)
{
$this->routeCollector = $routeCollector;
}
public function __invoke(ServerRequest $request, Response $response): ResponseInterface
{
$routes = $this->routeCollector->getRoutes();
// ...
}
}
This will display basic information about all routes in your app in SlimPHP 4:
$app->get('/tests/get-routes/', function ($request, $response, $args) use ($app) {
$routes = $app->getRouteCollector()->getRoutes();
foreach ($routes as $route) {
echo $route->getIdentifier() . " → ";
echo ($route->getName() ?? "(unnamed)") . " → ";
echo $route->getPattern();
echo "<br><br>";
}
return $response;
});
From there, one can use something like this to get the URL for a given route:
$routeParser = \Slim\Routing\RouteContext::fromRequest($request)->getRouteParser();
$path = $routeParser->urlFor($nameofroute, $data, $queryParams);
With the following caveats:
this will only work for named routes;
this will only work if the required route parameters are provided -- and there's no method to check whether a route takes mandatory or optional route parameters.
there's no method to get the URL for an unnamed route.

How to use createUser in Facebook Ads (to replace deprecated addUsers)

Now that I've upgraded to "facebook/php-ads-sdk": "2.8.*" (https://github.com/facebook/facebook-php-ads-sdk), this function of mine doesn't work anymore:
public function addToCustomAudience($entriesArray, $audienceId, $inputType = CustomAudienceTypes::EMAIL) {
$audience = new CustomAudience($audienceId);
$result = $audience->addUsers($entriesArray, $inputType);
return $result;
}
Apparently addUsers is no longer available.
I see a createUser function, but it looks quite different, and there is no documentation online about how to migrate from addUsers to createUser.
What I want to do is simple.
Given an array of email addresses and an ID of an audience, how can I add all of those email addresses to that Facebook Custom Audience?
From what I can see in the code, addUsers is still there, and it's documented on the Developer site.
I just used the latest SDK along with the following code to update an audience:
use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Values\CustomAudienceTypes;
$emails = array(
'test1#example.com',
'test2#example.com',
'test3#example.com',
);
$audience = new CustomAudience(<CUSTOM_AUDIENCE_ID>);
$audience->addUsers($emails, CustomAudienceTypes::EMAIL);
This seems to work for my purposes.
I copied some code from the facebook-php-ads-sdk as a workaround.
$audience = new CustomAudience($audienceId);
$params = $this->formatParams($entriesArray, $inputType, [], false);
$audience->createUser([], $params, false);
/**
* Copied this from Facebook's https://github.com/facebook/facebook-php-ads-sdk/blob/d51193b19d730ae9274d45540986e1ac311b074d/src/FacebookAds/Object/CustomAudience.php#L363
* Take users and format them correctly for the request
*
* #param array $users
* #param string $type
* #param array $app_ids
* #param bool $is_hashed
* #return array
*/
protected function formatParams(array $users, $type, array $app_ids = array(), $is_hashed = false) {
if ($type == CustomAudienceTypes::EMAIL || $type == CustomAudienceTypes::PHONE) {
$normalizer = new EmailNormalizer();
$hash_normalizer = new HashNormalizer();
foreach ($users as &$user) {
if ($type == CustomAudienceTypes::EMAIL) {
$user = $normalizer->normalize(CustomAudienceTypes::EMAIL, $user);
}
if (!$is_hashed) {
$user = $hash_normalizer->normalize(
CustomAudienceTypes::EMAIL, $user);
}
}
}
$payload = array(
'schema' => $type,
'data' => $users,
);
if ($type === CustomAudienceTypes::ID) {
if (empty($app_ids)) {
throw new \InvalidArgumentException(
"Custom audiences with type " . CustomAudienceTypes::ID . " require"
. "at least one app_id");
}
$payload['app_ids'] = $app_ids;
}
return array('payload' => $payload);
}

Zend insert user and set value to max()+1

My code:
public function insertMember($member)
{
$maxOrderNumber = $this->select()
->from($this, array(new Zend_Db_Expr('max(order_number)')));
$id = $this->insert($member, $maxOrderNumber);
return $id;
}
I want to insert member to last position in members table and order_number entity. Tried with $maxOrderNumber but i keep getting 0 value in database.
Im using MySql. Also i have user_id with (AI) Autoincrement so i'm forced to function this way.
public function insertMember($member)
{
$maxOrderNumber = $this->select()
->from($this, array(new Zend_Db_Expr('max(order_number)')));
$stmt = $maxOrderNumber ->query();
$result = $stmt->fetchAll();
$id = $this->insert($member, $result ['order_number']);
return $id;
}
soemthing like that...

How to inserting data from install.xml file into mysql database in moodle

In moodle site (use moodle Version 2.6.3), I have generated install.xml file by XMLDB editor, but it's use only to create table in database during plugin installation. I want to insert some default rows in the table also.
Any body can help me how to edit in install.xml file for insert data
To add data after an install, create a file called yourplugin/db/install.php with
UPDATE: added xml parser
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/xmlize.php');
function xmldb_yourpluginname_install() {
global $CFG, $OUTPUT, $DB;
// Your add data code here.
$xmltext = file_get_contents('import.xml');
$records = parse_xml($xmltext, 'records', 'record');
foreach ($records as $record) {
$DB->insert_record('yourtablename', $record);
}
}
/**
* Converts XML text into an array of stdclass objects.
*
* #param type $text - xmltext
* #param type $elementnames - plural name of elements
* #param type $elementname - name of element
* #return array|boolean - array of record objects
*/
function parse_xml($text, $elementnames, $elementname) {
// Seems that xmlize needs a lot of memory.
ini_set('memory_limit', '256M');
// Ensure content is UTF-8.
$content = xmlize($text, 1, 'UTF-8');
$records = array();
if (!empty($content[$elementnames]['#'][$elementname])) {
$rows = $content[$elementnames]['#'][$elementname];
foreach ($rows as $row) {
$fields = $row['#'];
$row = new stdClass();
foreach ($fields as $fieldname => $fieldvalue) {
$row->$fieldname = $fieldvalue[0]['#'];
}
$records[] = $row;
}
return $records;
}
return false;
}