Where to specify an app version on a Laravel app? - php

I used to specify the app version inside composer.json until I read somewhere here in Stack Overflow that it was a bad practice. What is the standard file to specifying the app version on a PHP Laravel application? (i.e: in .NET that'd be the config file, on iOS it'd be the info.plist, on Android it'd be the Manifest, etc...)

config/app.php is definitely the place for such information.
Why ? Because the configuration files are (or should be) included in your versioning flow and they (should) contain non-sensitive information about your application. The perfect place for a simple version indicator.
under the name index of the array, you could set a version index like this
/*
|--------------------------------------------------------------------------
| Application Version
|--------------------------------------------------------------------------
|
| This value is the version of your application. This value is used when
| the framework needs to place the application's version in a notification
| or any other location as required by the application or its packages.
*/
'version' => '1.0.0',

#delatbabel
has a great start for version
config/app.php
'version' => env('APP_VERSION', '1.0.0'),
for config/bugsnag:
'app_version' => env('APP_VERSION', '1.0.0'),
then you can simply get your version with:
config('app.version')
Docker
now in docker you could set a default version on build:
ENV APP_VERSION=1.0.0
for example with circle CI you can add your build number:
ARG BUILD_NR
ENV APP_VERSION=1.0.$BUILD_NR
Now in your config.yml, you can add following job commando:
deliver-prod:
machine: true
steps:
- checkout
- docker build --build-arg BUILD_NR=$CIRCLE_BUILD_NUM .

I normally set it in my .env file and then pick that up in a config.
e.g. .env says:
APP_VERSION=2.1
config/app.php says:
'version' => env('APP_VERSION', '0.0.1-alpha'),

My approch for now: GitLab pipeline writes the "version.php" file after every successful build. The file has the following content:
<?php const VERSION = '1.2.3';
In the "config/app.php" I include the file
require_once __DIR__ . '/../version.php';
...
'version' => VERSION,
...
The version can be queried as follows (e.g. as a route):
Route::get('api/version', function () {
return ["version" => config('app.version')];
})
->name('version');

Related

Laravel Carbon\Carbon::setLastErrors()

I have this laravel api hosted on a sharefd hosting siteground, i made some changes like changing the public folder to public html and update the storage filing so i can be able to run the laravel storage link commande bu i encountred this error while trying to access my temporary domain
FULL ERROR NAME
Carbon\Carbon::setLastErrors(): Argument #1 ($lastErrors) must be of type array, bool given, called in /home/customer/www/bassemb5.sg-host.com/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php on line 98
and this is my index.php looks like
<?php
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Check If The Application Is Under Maintenance
|--------------------------------------------------------------------------
|
| If the application is in maintenance / demo mode via the "down" command
| we will load this file so that any pre-rendered content can be shown
| instead of starting the framework, which could cause an exception.
|
*/
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
require $maintenance;
}
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| this application. We just need to utilize it! We'll simply require it
| into the script here so we don't need to manually load our classes.
|
*/
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request using
| the application's HTTP kernel. Then, we will send the response back
| to this client's browser, allowing them to enjoy our application.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
$app->bind('path.public', fn() => base_path('/public_html'));
$kernel = $app->make(Kernel::class);
$response = $kernel->handle(
$request = Request::capture()
)->send();
$kernel->terminate($request, $response);
and this is the line i added and it was working perfectly
$app->bind('path.public', fn() => base_path('/public_html'));
Hi Also managing my old site.
You need to update your composer by using
composer update
And all work fine
We had exactly the same error (same file and line) than OP.
In our research it looks like it got broken after 2.57 (working), for us 2.58 was already failing and broke our pipeline, failing in the "composer install" phase with exactly same error.
As #tomexsans mentions it seems to be fixed in 2.62.1+. We upgraded to the latest available version today (2.64) and worked fine, getting the issue fixed.
--
TL;DR
composer update nesbot/carbon
should do the trick.
Also managing my old site on Siteground, customer contacted told me about 500 error.
When I looked at the Logs nothing is wrong.
When I turned on the app_debug we had the same error.
It does not happen on localhost because I have PHP 8.1 installed.
If you're using PHP 8.2 and this problem appears, you need to update your composer.lock to the latest carbon version
https://github.com/briannesbitt/Carbon/releases/tag/2.62.1
or just pull back your PHP version to 8.1
UPDATE: this error came from Siteground Auto Updating your PHP VERSION to 8.2
I have mine forced to PHP 8.1 yet they still Auto Managed it and upgraded the PHP Version to 8.2 without any notifications or advise
I had this issue a few days again
just type composer update on your terminal that will solve the issue.
Give this a vote afterward.
We used carbon in combination with aporat - store receipt validator.
Unfortunately we couldn't update the nesbot using composer, due hardlocked versions and nesbot being a dependency of another library.
Luckily when comparing the libraries Creator file we saw the hotfix in the latest version, by that time being:
https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Traits/Creator.php
We ended up fixing it with only updating that specific file, since only the setLastErrors() function was updated there.
I truly hope it helps someone.
If you can not change your PHP version to 8.1, you can update this line
File Path
./vendor/nesbot/carbon/src/Carbon/Traits/Creator.php
Line No:
928
Old Line
private static function setLastErrors(array $lastErrors)
New Line
private static function setLastErrors($lastErrors)

Gitlab CI configuration with Laravel Docker Redis wrong host or port

I'm working on a Gitlab CI configuration in the .gitlab-ci.yml file for a Laravel project which uses redis as Cache Driver. Within this configuration file I use an image which has all the linux packages, php extension which are used on our production environment. This includes the redis extension installed by pecl so phpredis can be used within Laravel.
After spending a fair amount of time into learning the process of continuous integration and the configuration of the gitlab ci file I encountered the following error on deploy of the image:
In PhpRedisConnector.php line 126:
Redis::connect() expects parameter 2 to be int, string given
parameter should be only the port as an int but somehow turned into tcp://111.111.11.11:6379
As documented https://docs.gitlab.com/ee/ci/services/redis.html the host in your .env should be redis so I had. Dumping the config during the deploy resulted in port being some tcp://111.111.11.11:6379 connection string and host being empty. There is no way this is changed within our application or any extension we use.
I use the https://hub.docker.com/_/redis/ as a service in the .gitlab-ci.yml.
...
services:
- name: redis:4
...
Solution found here:
https://laracasts.com/discuss/channels/testing/gitlab-ci-weird-redis-host
This variable isn't documented anywhere but somehow it solves the problem.
Add the following to your .gitlab-ci.yml file:
variables:
REDIS_PORT: 6379
If anyone finds documentation about this variable and maybe more options, let me know!
This is expected behaviour from Docker.
In Gitlab CI, all services you define will be linked with your container which is running your job using Docker linking system.
As describe here, when we link containers, Docker automatically creates ENVs in format:
<_alias>_NAME
<_alias>_PORT
and some other ENVS
And those ENVs from Docker will override yours.
alias here will be the hostname of your container you defined in services. For example you define these services in your .gitlab-ci.yml:
services:
- redis:5-alpine
- name: mongo
alias: db
So Docker will create the following ENVs respectively:
REDIS_PORT="some thing looks like: tcp://172.17.0.3:6379"
REDIS_NAME="looks like: /runner-72989761-project-19846207-concurrent-0-62507216079cf651-build-3/redis"
DB_PORT=same like redis
DB_NAME=same like redis
And note that, as described here, by default the following ENVs are also auto created based on service image's name:
MONGO_PORT=...
MONGO_NAME=...
So in your code if you have any variable that has same name with the ones Docker creates, you may need to change your variable's name otherwise it'll be override by Docker. Or you can use the solution from #MmynameStackflow above, pass variables in your Gitlab CI config file to override what Docker does.

Composer package where to put client config?

I have a composer package designed for use in other projects that has configurations, or rather default settings I'd like the end user to be able to adjust based on their intended use. The package itself can be configured to build things differently depending on the configurations passed to the package's builder class. I'd like there to be default settings, possibly in a settings.yml file (the medium is not a concern, *.conf, *.json, *.php), may be this should go within the package? But then I imagine if that were the case it would be hard for the end user to maintain as it would be overwritten during composer updates? Anyone know what the norm for storing composer vendor packages configs is?
$parameters = [
'handlers' => [
// various depending on client use
'//widget' => 'LivingMarkup\Component\Widgets\{name}',
'//img' => 'LivingMarkup\Component\Img',
'//a' => 'LivingMarkup\Component\A',
'//var' => 'LivingMarkup\Component\Variable',
'//condition' => 'LivingMarkup\Component\Condition',
'//redact' => 'LivingMarkup\Component\Redact'
],
'hooks' => [
'beforeLoad' => 'Executed before onLoad',
'onLoad' => 'Loads object data',
'afterLoad' => 'Executed after onLoad',
'beforeRender' => 'Executed before onLoad',
'onRender' => 'RETURN_CALL',
'afterRender' => 'Executed after onRender',
]
];
Thank you.
After a bit more searching I found a post that addresses this exact question.
https://www.reddit.com/r/PHP/comments/3qqrmz/how_to_handle_config_files_and_default_settings/
To summarize, in case the above link stops working some day, here are some options:
"Bolt CMS does uses a config.yml.dist, which is included with the source code. And the end user can create a config.yml file if one doesn't exist. The config.yml.dist file is part of the official project and acts as the example config file, and should not be modified."
"Your own config.yml file can be tracked in your version control if you wish. Then you can put confidential or environment-specific information into config_local.yml and place that file's name in .gitignore."
"Symfony I use the parameters.yml and config.yml to pass parameters to the objects in DIC."
"Phpunit uses the phpunit.xml.dist file to setup tests."
"Apigen uses .neon or .yaml config files."
"Flysystem asks for config options to be passed directly in the constructor"
"Cakephp has it's own configuration settings, and plugins come with instructions on the keys to add. This asset compress package uses an ini file"
Opus is an option: https://github.com/imarc/opus

Using local google Datastore with dev_appserver.pyp

At the moment I am able to write to the datastore once I deploy my code, but I can't write to the datastore emulator with code running locally since it throws a ca-bundle error. The local datastore is visible at localhost:8000
use google\appengine\api\users\User;
use google\appengine\api\users\UserService;
use google\appengine\api\app_identity\AppIdentityService;
echo AppIdentityService::getApplicationId()."<br>";
echo AppIdentityService::getDefaultVersionHostname()."<br>";
# Includes the autoloader for libraries installed with composer
require __DIR__ . '/vendor/autoload.php';
use Google\Cloud\ServiceBuilder;
$cloud = new ServiceBuilder([
'projectId' => AppIdentityService::getApplicationId(),
'keyFilePath'=>'review-9504000716d8.json'
]);
$datastore = $cloud->datastore();
# The kind for the new entity
$kind = 'Task';
# The name/ID for the new entity
$name = 'sampletask1';
# The Cloud Datastore key for the new entity
$taskKey = $datastore->key($kind, $name);
# Prepares the new entity
$task = $datastore->entity($taskKey, ['description' => 'Buy milk']);
# Saves the entity
$datastore->upsert($task);
This code runs without any issues when deployed. But locally throws:
Fatal error: Uncaught exception 'Google\Cloud\Exception\ServiceException' with message 'No system CA bundle could be found in any of the the common system locations. PHP versions earlier than 5.6 are not properly configured to use the system's CA bundle by default. In order to verify peer certificates, you will need to supply the path on disk to a certificate bundle to the 'verify' request option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not need a specific certificate bundle, then Mozilla provides a commonly used CA bundle which can be downloaded here (provided by the maintainer of cURL): https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path to the file, allowing you to omit the 'verify' request option. See http://curl.haxx.se/docs/sslcerts.html for more information.' in D:\Google\php\appengine-php-guestbook-phase0-helloworld\appengine-php-guestbook-phase0-hellowo in D:\Google\php\appengine-php-guestbook-phase0-helloworld\appengine-php-guestbook-phase0-helloworld\vendor\google\cloud\src\RequestWrapper.php on line 219
I didn't manage to make the local server even consider the php.ini file nor did I manage to upgrade the bundled php55 to at least php56.
Thus I actually have 2 questions:
how to properly connect from the local instance (dev_appserver.py) on windows to Google's remote datastore?
how to properly connect from the local instant to the local emulated datastore so I can view the data on localhost:8000?
The APIs are using CA certificate files for authentication more specifically they are using curl.cainfo.
Now you server might already have this file configured in php.ini. You can check in server file. Remember there could be different ini files for different environments like apache, cli.
Now you can either copy that file or Create your own authority file
Option 1:
Set absolute path in php.ini
Option 2:
Use ini_set to set this config.
Option 3:
Try with some other mode of authentication, i am sure google will have that.
Option 4:
As given in your question itself.
If you do not need a specific certificate bundle, then Mozilla provides a commonly used CA bundle which can be downloaded here
https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path to the file, allowing you to omit the 'verify' request option

Laravel 4 - environment configuration

I am working on a Laravel 4 project and I need to be able to switch between multiple configurations. So as far as I know Laravel enables me to configure envs based on URL like this in the start.php
$env = $app->detectEnvironment(array(
'local' => array('localhost'),
'stage' => array('project.stage.com'),
'prod' => array('project.production.com'),
));
And each of this configs consists of separate database connections and other configuration files. What I want is on my local environment to be able to switch between local,stage and prod, so for example if I want to connect to the prod database from my local project to test something. As far as I can understand if I want to do this I need to manualy switch the database connection strings in the local configuration. Is there any other way for switching between configurations on local level ? Hope my question was clear.
You can pass a closure to the function to determine set the environment more dynamically. You can either replicate the logic laravel uses and only use the closure in combination with gethostname() or just comment the part out and add this for testing:
$app->detectEnvironment(function(){
return 'stage';
});

Categories