For the currency conversion i am using "florianv/laravel-swap": "^1.1" library. Florianv/Laravel-swap.
As Fixer.io has changed its implementation, it is necessary to pass the access_key with the request, and because of that i am getting this error: "InvalidArgumentException: The "access_key" option must be provided to use fixer.io in /var/www/project/project-files/vendor/florianv/exchanger/src/Service/Fixer.php:51".
I registered and got the access_key.
I updated the library using composer and now i can see three constants in the vendor/florianv/exchanger/src/Service/Fixer.php.
const ACCESS_KEY_OPTION = 'access_key';
const LATEST_URL = 'http://data.fixer.io/api/latest?base=%s&access_key=%s';
const HISTORICAL_URL = 'http://data.fixer.io/api/%s?base=%s&access_key=%s';
To pass the access key i tried this:
I have a swap.php in config folder which looks something like this:
return [
'options' => [
'cache_ttl' => 86400, // 24 hours.
'cache_key_prefix' => 'currency_rate'
],
'services' => [
'fixer' => true,
],
'currency_layer' => [
'access_key' => 'asdfas7832mw3nsdfa776as8dfa', // Your app id
'enterprise' => true, // True if your AppId is an enterprise one
],
'cache' => env('CACHE_DRIVER', 'file'),
'http_client' => null,
'request_factory' => null,
'cache_item_pool' => null,
];
This had one more option which was commented, i enabled and passed the access_key in it but it doesn't work.
I also added it in services block below 'fixer => true'.
'currency_layer' => [
'access_key' => 'asdfas7832mw3nsdfa776as8dfa'
]
Also in options block:
'options' => [
'cache_ttl' => 86400, // 24 hours.
'cache_key_prefix' => 'currency_rate',
'access_key'=>'7ca208e9136c5e140d6a14427bf9ed21'
],
I tried with adding access_key in config/services.php file but it also didn't work.
'fixer' => [
'access_key' => 'asdfas7832mw3nsdfa776as8dfa'
],
Even i tried, adding to env file and calling from there, but no success. How do i pass the access_key, can anyone help me on this, what should be the approach.
vendor/florianv/exchanger/src/Service/Fixer.php -> don't touch the constant (that was my own error).
Pass the options-array by creating the Builder:
$options = ['access_key' => 'YourGeneratedAPIKeyAtCurrencyLayer'];
$this->exchangeSwap = (new Builder($options))
->add('fixer', $options )
->build();
I hope I could help ;-)
Related
I'm writing a couple of laravel packages and I'm wondering if it is possible to have the package write to a specific log file but only for messages related to the package?
I tried making a logging.php file in the packages/myorg/mypackage/config (below) but it doesn't seem to do anything.
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/mypackage.log'),
'level' => env('LOG_LEVEL', 'debug'),
]
]
];
I am using "jeroen-g/laravel-packager" to set up the packages. It appears to manually load the mypackage.config in the ServiceProvider bootForConsole
protected function bootForConsole(): void
{
// Publishing the configuration file.
$this->publishes([
mypackage.'/../config/mypackage.php' => config_path('mypackage.php'),
], 'mypackage.config');
}
I'm not sure how to add custom logging to that though. I'm still learning Laravel and I'm not quite sure what or how the main applications config/logging.php is read so I'm not quite sure how to inject a custom version for an add-on package.
EDIT:
I found a post that suggested using the following in the ServiceManager boot() method:
$this->app->make('config')->set('logging.channels.mychannel', [
/* settings */
]);
I used the package config to set a 'logging' => [ 'channels' => [ 'mychannel' => [ /* settings */ ] ] ] and could then do the same thing as above with:
$this->app->make('config')->set('logging.channels.mychannel', config('mypackage.logging.channels.mychannel');
But that still required something in the code. The next best thing I have found thus far is to change my config/logging.php to config/logging.channels.php and include something like:
return [
'mychannel' => [
'driver' => 'single',
'path' => storage_path('logs/mypackage.log'),
'level' => env('LOG_LEVEL', 'debug'),
]
];
Then in the service provider register() method add:
$this->mergeConfigFrom(__DIR__ . '/../config/logging.channels.php', 'logging.channels');
I tried doing it from the original 'logging.php' with channels array nested in a 'logging' key, but array_merge doesn't appear to merge the nested elements so my channel never showed up in logging.channels.
I'm not sure if this is ideal, however. I'd still like to know if there is a 'better' or best practices way of adding custom package logging parameters and whether there is a need to publish it in any way (and how).
I am trying to save a string with one application to memcached. And then after an http redirect, trying to retrieve that information from a different application on the same server. I am able to save, but retrieving the information is not working.
I have made sure that both applications are not applying a prefix to the cache key. I have run 'memcached-tool localhost:11211 dump | less' on the memcache server to ensure the data exists, which it does. I can access the data from the same application that saves the data. So if I save from the Laravel app, I can retrieve from the laravel app, and vice versa for the phalcon app.
The environment variables used are the same in both apps.
Setup in Laravel (cache.php):
'memcached' => [
'driver' => 'memcached',
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 0,
],
],
],
How I am saving in Laravel:
Cache::put($sha, $viewData, 60);
return redirect("someUrl/{$sha}", 302);
Setup in Phalcon:
$di->setShared('memcached', function(){
// Cache data for one hour
$frontCache = new \Phalcon\Cache\Frontend\Data(
[
'lifetime' => 60,
'prefix' => ''
]
);
// Create the component that will cache 'Data' to a 'Memcached' backend
// Memcached connection settings
return new \Phalcon\Cache\Backend\Libmemcached(
$frontCache,
[
'prefix' => '',
'servers' => [
[
'host' => MEMCACHED_SERVER,
'port' => MEMCACHED_PORT,
'weight' => 0,
]
]
]
);
});
How I am trying to retrieve info in Phalcon:
$cache = $this->di->getShared('memcached');
$info = $cache->get($cacheKey);
Here is the output of the $cache var from xdebug:
Phalcon\Cache\Backend\Libmemcached::__set_state(array(
'_frontend' =>
Phalcon\Cache\Frontend\Data::__set_state(array(
'_frontendOptions' =>
array (
'lifetime' => 60,
'prefix' => '',
),
)),
'_options' =>
array (
'prefix' => '',
'servers' =>
array (
0 =>
array (
'host' => 'servername',
'port' => port,
'weight' => 0,
),
),
'statsKey' => '',
),
'_prefix' => '',
'_lastKey' => '38404efbc4fb72ca9cd2963d1e811e95fe76960b',
'_lastLifetime' => NULL,
'_fresh' => false,
'_started' => false,
'_memcache' =>
Memcached::__set_state(array(
)),
))
And here is the dump from memcached-tool:
Dumping memcache contents
add 38404efbc4fb72ca9cd2963d1e811e95fe76960b 4 1562346522 144
a:5:{s:3:"zip";s:0:"";s:10:"first_name";s:5:"Clint";s:9:"last_name";s:9:"Broadhead";s:5:"phone";s:0:"";s:5:"email";s:20:"blah#blah.com";}
I expected to be able to save to memcache from any application and then retrieve that cache from anywhere else that has access to the same server. But when I try to retrieve in the phalcon app I receive 'null'. Even though I can see the key/value pair on the server. Thanks in advance for your assistance.
I bypassed using Phalcons built-in backend and frontend classes and just went with using the PHP ext-memcached on the phalcon app.
$di->setShared('memcached', function(){
if( !($this->_memcache instanceof \Memcached) ){
if( !class_exists('Memcached') ){
throw new CacheException('Unable to connect to cache');
}
$this->_memcache = new \Memcached();
$this->_memcache->addServer(MEMCACHE_SERVER, MEMCACHE_PORT)
return $this->_memcache;
}
});
I started to go down the path of phalcons use of '_PHCM', but once the above solution worked I abandoned that research. Not the best, but works well for my temporary situation.
Phalcon uses prefixes for all cache keys by default. For the Libmemcached adapter
For instance the get for the Libmemcached adapter has:
let prefixedKey = this->_prefix . keyName;
let this->_lastKey = prefixedKey;
let cachedContent = memcache->get(prefixedKey);
https://github.com/phalcon/cphalcon/blob/3.4.x/phalcon/cache/backend/libmemcached.zep#L160
Just make sure that there are no prefixes by setting the prefix option in your options
$di->setShared('memcached', function(){
// Cache data for one hour
$frontCache = new \Phalcon\Cache\Frontend\Data(
[
'lifetime' => 60,
]
);
// Create the component that will cache 'Data' to a 'Memcached' backend
// Memcached connection settings
return new \Phalcon\Cache\Backend\Libmemcached(
$frontCache,
[
'prefix' => '',
'servers' => [
[
'host' => MEMCACHED_SERVER,
'port' => MEMCACHED_PORT,
'weight' => 0,
]
]
]
);
});
https://github.com/phalcon/cphalcon/blob/3.4.x/phalcon/cache/backend.zep#L59
Finally if the above does not work, install a utility that will allow you to query your Memcached instance and see what keys are stored there. Check it before you store data with Laravel and then afterwards. This way you will know whether you check the correct thing or not.
Alternatively you can use good old telnet if you are comfortable with the command line to check the keys.
I have a Laravel 5 project that is using the bepsvpt/secure-headers package with the following config file:
config/secure-headers.php
<?php
return [
'x-content-type-options' => 'nosniff',
'x-download-options' => 'noopen',
'x-frame-options' => 'sameorigin',
'x-permitted-cross-domain-policies' => 'none',
'x-xss-protection' => '1; mode=block',
/*
* Referrer-Policy
*
* Reference: https://w3c.github.io/webappsec-referrer-policy
*
* Available Value: 'no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin',
* 'same-origin', 'strict-origin', 'strict-origin-when-cross-origin', 'unsafe-url'
*/
'referrer-policy' => 'strict-origin-when-cross-origin',
'hsts' => [
'enable' => env('SECURITY_HEADER_HSTS_ENABLE', false),
'max-age' => 15552000,
'include-sub-domains' => false,
],
/*
* Content Security Policy
*
* Reference: https://developer.mozilla.org/en-US/docs/Web/Security/CSP
*
* csp will be ignored if custom-csp is not null.
*
* Note: custom-csp does not support report-only.
*/
'custom-csp' => env('SECURITY_HEADER_CUSTOM_CSP', null),
'csp' => [
'report-only' => false,
'report-uri' => env('CONTENT_SECURITY_POLICY_REPORT_URI', false),,
'upgrade-insecure-requests' => false,
'base-uri' => [
//
],
'default-src' => [
//
],
'child-src' => [
//
],
'script-src' => [
'allow' => [
//
],
'hashes' => [
// ['sha256' => 'hash-value'],
],
'nonces' => [
//
],
'self' => false,
'unsafe-inline' => false,
'unsafe-eval' => false,
],
'style-src' => [
'allow' => [
//
],
'self' => false,
'unsafe-inline' => false,
],
'img-src' => [
'allow' => [
//
],
'types' => [
//
],
'self' => false,
'data' => false,
],
/*
* The following directives are all use 'allow' and 'self' flag.
*
* Note: default value of 'self' flag is false.
*/
'font-src' => [
//
],
'connect-src' => [
//
],
'form-action' => [
//
],
'frame-ancestors' => [
//
],
'media-src' => [
//
],
'object-src' => [
//
],
/*
* plugin-types only support 'allow'.
*/
'plugin-types' => [
//
],
],
];
When I try to run the application (web request or php artisan), I get the following error:
PHP Fatal error: Cannot use empty array elements in arrays in C:\Web\myapp\config\secure-headers.php on line 4
Of course, line 4 of the file looks totally fine!
What is the issue here?
This error, which is not documented anywhere I can find online, comes from having two commas in a row with nothing between them inside the array.
In my case, this actually appeared on line 42 of the file, not line 4 as indicated by the error message, which sounds like a bug in the compiler which identifies the first item in the array instead of the actual location of the "empty array element".
NOTE: In PHP 7.2.15+, 7.3.2+, and 7.4.0+, the error message has been changed to report the line number of the previous valid element instead of the line number of the beginning of the array. While this may still be off by one or more lines, it is usually close enough to the problem to make it much easier to find.
I got the same error, while pointing at line 2, the error was on line 6.
I spent hours troubleshooting helplessly because it was a familiar code and I didn't know when an extra , got at the back of 'available' => $faker->boolean(85),
return [
'id' => $id,
'user_id' => $id,
'slug' => $slug,
'speciality' => $faker->randomElement(['Option A','Optoin B']),
'available' => $faker->boolean(85),,
'subscription_ends_at' => $faker->dateTimeBetween('-5 day', '30 day'),
'verified_at' => $faker->dateTimeBetween('-50 day', '-16 minute'),
];
Simply search your code for ,, or spaces between two commas , , on the same line as pointed out by #Moshe Katz.
This thread is a life saver.
I got this error and yes, the line indicated as where the error happened was wrong(Error was on line 10 instead of line 2 of the code below):
return Http::response(
["popularity" => 113.485,
"vote_count" => 9016,
"video" => false,
"poster_path" => "/qa6HCwP4Z15l3hpsASz3auugEW6.jpg",
"id" => 920,
"adult" => false,
"backdrop_path" => "/8KeWhoMpqbzZRyHPkTtWSLWkL5L.jpg",
"original_language" => "en",
"original_title" => "Cars",
"genre_ids" => [,
0 => 12,
1 => 16,
2 => 35,
3 => 10751,
],
"title" => "Cars",
"vote_average" => 6.8,
"overview" => "Lightning McQueen, a hotshot rookie race car driven to succeed, discovers that life is about the journey, not the finish line, when he finds himself unexpectedly detoured in the sleepy Route 66 town of Radiator Springs. On route across the country to the big Piston Cup Championship in California to compete against two seasoned pros, McQueen gets to know the town's offbeat characters.",
"release_date" => "2006-06-08",
]);
The issue was from a typo where I added a comma after the square bracket resulting in "[,"
So if you try the suggestions above and it doesn't work, look for a "[," and remove the trailing comma.
I m using a basic template for a small project on Yii2. I have already set the module Language Picker of Lajax (Doc) and I am trying now to manage the translation with the module Translate Manager of Lajax (Github). The plugin is scanning perfectly the project and getting the translatable texts. I even set some translations through this module and everything is saved in the database, but these translations are not set when changing the language.
here are my web.php Configurations:
'language' => 'en-GB',
'components' => [
...
'languagepicker' => [
'class' => 'lajax\languagepicker\Component',
'languages' => ['en-GB', 'fr-FR']
],
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\DbMessageSource',
'db' => 'db',
'sourceLanguage' => 'en-GB',
'sourceMessageTable' => '{{%language_source}}',
'messageTable' => '{{%language_translate}}',
'forceTranslation' => true,
'cachingDuration' => 86400,
'enableCaching' => true,
],
],
],
...
]
'modules' => [
...
'translatemanager' => [
'class' => 'lajax\translatemanager\Module',
'root' => '#app', // The root directory of the project scan.
'scanRootParentDirectory' => false, // Whether scan the defined `root` parent directory, or the folder itself.
// IMPORTANT: for detailed instructions read the chapter about root configuration.
'layout' => 'language', // Name of the used layout. If using own layout use 'null'.
'allowedIPs' => ['127.0.0.1'], // IP addresses from which the translation interface is accessible.
'roles' => ['#'], // For setting access levels to the translating interface.
'tmpDir' => '#runtime', // Writable directory for the client-side temporary language files.
// IMPORTANT: must be identical for all applications (the AssetsManager serves the JavaScript files containing language elements from this directory).
'phpTranslators' => ['::t'], // list of the php function for translating messages.
'jsTranslators' => ['lajax.t'], // list of the js function for translating messages.
'patterns' => ['*.js', '*.php'],// list of file extensions that contain language elements.
'ignoredCategories' => ['yii'], // these categories won't be included in the language database.
'ignoredItems' => ['config'], // these files will not be processed.
'scanTimeLimit' => null, // increase to prevent "Maximum execution time" errors, if null the default max_execution_time will be used
'searchEmptyCommand' => '!', // the search string to enter in the 'Translation' search field to find not yet translated items, set to null to disable this feature
'defaultExportStatus' => 1, // the default selection of languages to export, set to 0 to select all languages by default
'defaultExportFormat' => 'json',// the default format for export, can be 'json' or 'xml'
'tables' => [ // Properties of individual tables
[
'connection' => 'db', // connection identifier
'table' => '{{%language}}', // table name
'columns' => ['name', 'name_ascii'],// names of multilingual fields
'category' => 'database-table-name',// the category is the database table name
]
],
'scanners' => [ // define this if you need to override default scanners (below)
'\lajax\translatemanager\services\scanners\ScannerPhpFunction',
'\lajax\translatemanager\services\scanners\ScannerPhpArray',
'\lajax\translatemanager\services\scanners\ScannerJavaScriptFunction',
'\lajax\translatemanager\services\scanners\ScannerDatabase',
],
],
...
]
I always use something like this im code for translatable strings:
<?= Yii::t('app','Test') ?>
Am I doing something wrong?
I am working on a project where we will be creating both subdomains as well as domains in Route53. We are hoping that there is a way to do this programmatically. The SDK for PHP documentation seems a little light, but it appears that createHostedZone can be used to create a domain or subdomain record and that changeResourceRecordSets can be used to create the DNS records necessary. Does anyone have examples of how to actually accomplish this?
Yes, this is possible using the changeResourceRecordSets call, as you already indicated. But it is a bit clumsy since you have to structure it like a batch even if you're changing/creating only one record, and even creations are changes. Here is a full example, without a credentials method:
<?php
// Include the SDK using the Composer autoloader
require 'vendor/autoload.php';
use Aws\Route53\Route53Client;
use Aws\Common\Credentials\Credentials;
$client = Route53Client::factory(array(
'credentials' => $credentials
));
$result = $client->changeResourceRecordSets(array(
// HostedZoneId is required
'HostedZoneId' => 'Z2ABCD1234EFGH',
// ChangeBatch is required
'ChangeBatch' => array(
'Comment' => 'string',
// Changes is required
'Changes' => array(
array(
// Action is required
'Action' => 'CREATE',
// ResourceRecordSet is required
'ResourceRecordSet' => array(
// Name is required
'Name' => 'myserver.mydomain.com.',
// Type is required
'Type' => 'A',
'TTL' => 600,
'ResourceRecords' => array(
array(
// Value is required
'Value' => '12.34.56.78',
),
),
),
),
),
),
));
The documentation of this method can be found here. You'll want to take very careful note of the required fields as well as the possible values for others. For instance, the name field must be a FQDN ending with a dot (.).
Also worth noting: You get no response back from the API after this call by default, i.e. there is no confirmation or transaction id. (Though it definitely gives errors back if something is wrong.) So that means that if you want your code to be bulletproof, you should write a Guzzle response handler AND you may want to wait a few seconds and then run a check that the new/changed record indeed exists.
Hope this helps!
Yes, I done using changeResourceRecordSets method.
<?php
require 'vendor/autoload.php';
use Aws\Route53\Route53Client;
use Aws\Exception\CredentialsException;
use Aws\Route53\Exception\Route53Exception;
//To build connection
try {
$client = Route53Client::factory(array(
'region' => 'string', //eg . us-east-1
'version' => 'date', // eg. latest or 2013-04-01
'credentials' => [
'key' => 'XXXXXXXXXXXXXXXXXXX', // eg. VSDFAJH6KXE7TXXXXXXXXXX
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXX', //eg. XYZrnl/ejPEKyiME4dff45Pds54dfgr5XXXXXX
]
));
} catch (Exception $e) {
echo $e->getMessage();
}
/* Create sub domain */
try {
$dns = 'yourdomainname.com';
$HostedZoneId = 'XXXXXXXXXXXX'; // eg. A4Z9SD7DRE84I ( like 13 digit )
$name = 'test.yourdomainname.com.'; //eg. subdomain name you want to create
$ip = 'XX.XXXX.XX.XXX'; // aws domain Server ip address
$ttl = 300;
$recordType = 'CNAME';
$ResourceRecordsValue = array('Value' => $ip);
$client->changeResourceRecordSets([
'ChangeBatch' => [
'Changes' => [
[
'Action' => 'CREATE',
"ResourceRecordSet" => [
'Name' => $name,
'Type' => $recordType,
'TTL' => $ttl,
'ResourceRecords' => [
$ResourceRecordsValue
]
]
]
]
],
'HostedZoneId' => $HostedZoneId
]);
}
If you get any error please check into server error.log file. If you get error from SDK library then there is might PHP version not supported.
if you run this code from your local machine then you might get "SignatureDoesNotMatch" error then Make sure run this code into same (AWS)server environment.