Yii2 how to update other projects when base project is updated? - php

We currently have Yii2 base project (we can say, like, project root from which we will create other projects). Right now there are several modules, models, controllers and viewers. Everything is fine here but how to deploy (and where) so that when we update base project, all child projects that were using our base project would be updated (best is through Composer with composer update).
For example, Kartik has its plugins/widgets and we can simply update through Composer with command like $ php composer.phar require kartik-v/yii2-grid "#dev".
So we want to have something similar, but not accessible publicly (so that random people couldn't access without some sort of email/username/password). This part is not as important as the first part because in this part we at least can use something like BitBucket. There aren't many possible solutions, most likely a few only, actually, but it's a challenge that we cannot solve right now.
I have tried StackExchange but it's not as popular StackOverflow, so I'm trying to give as much information as I can. Assuming I see this question, this question shouldn't be off-topic either. Thanks!

You could use your own private repository for keeping yii2 app template. To update all your projects use composer. Here's code example:
"repositories": [
{
"type":"package",
"package": {
"name": "repo-name/yii2template",
"version":"master",
"source": {
"url": "https://your-git-server.com/repo-name/yii2template.git",
"type": "git",
"reference":"master"
}
}
}
],
So when you make changes to your template, you just update composer for certain project and get those changes.
P.S. Another idea is Ansible. You can update child projects by this tool, but you have to write playbook manually for your needs.
If you need this template local only, you could use PhpStorm, it can make templates from project.

Related

Laravel + Vue frontend decoupling with optional server-side Blade rendering

Let's say that there's a CMS made with Laravel. We would be providing different clients with that same CMS, upgrade their CMS on every release we create but have a configuration file that would define what features are available for each client. The entire backoffice (admin panel etc.) would be mostly static and would use Vue only for certain dynamic elements. This solution suits our needs when it comes to the backend.
However, we plan on deploying different end-user frontends for each of these clients. Decoupling those sounds very simple (create a completely separate frontend project and use API endpoints to fetch and render everything dynamically) but if we were to completely decouple the frontend and the backend we would lose the ability to render static pages using Laravel Blade and we need that feature for the certain pages because of the rendering speed, loading times, SEO etc.
The main question is: how to decouple the frontend from the backend for each client without losing the ability to render pages with Laravel and Blade while keeping the development and testing easy?
One of the solutions that comes to my mind is to create a post-build step where we would "merge" the client-specific frontend files into the CMS but this would make the development process very difficult or would even make it all practically impossible to develop and test.
The second solution that comes to my mind would be to:
Keep everything in one Git repository.
Develop the CMS on it's own branch and develop only the backend and backoffice stuff on that branch and it's children.
Create separate branches (What's the best practice for putting multiple projects in a git repository? perhaps some of the solutions presented here?) for different end-user frontends and develop only the end-user frontend on those branches.
Merge the CMS branch into the client branches on each release.
This solution seems viable and would allow us to use Laravel Mix and server-side rendering but it's very prone to human error and it would make it very difficult for us to keep track of these branches after a while. One of the other potential solutions that I've read about is using Git submodules but I simply have difficulty grasping how that works and it seems that it is not as flexible as it should be in this use case.
What would actually be the best architectural solution for us here?
I would think of your CMS as a package, and think of your different front-end pieces as separate projects that each have a dependency on your CMS. For instance, I use Backpack for Laravel for a number of projects: https://github.com/Laravel-Backpack/CRUD which I think is similar to what you're describing - a common set of core functionality with an un-opinionated front-end.
Laravel packages can register routes, publish views and assets, pull in migrations, etc etc - really anything you can do in a Laravel app can be done via a composer package.
So you would take the functionality that is repeated between your builds, and extract that into a "core" package that can be required via composer. Then the front-end stuff can be built in projects that simply require your core codebase. When you update your main core package, you can go into each front-end build and pull in the new version of the core via composer. This would give you an opportunity to roll the new core version out to each project one-by-one, making sure you can resolve issues or adapt to breaking changes on those projects individually.
Your core package can also include any front-end components that are commonly re-used across your client projects, so ideally you aren't re-writing any code between the front end projects.
It can be challenging to make that core code modular enough to be a standalone package, but I think that makes the most sense based on what I understand about your project. Hope it helps.
When you´re decoupling your system I strongly suggest not to pick the easiest solution without first guarantee it can scale and be ( as one of your concerns is ) easy to test.
Let´s call your core product CMS vanilla, it works as supposed and designed to be. Now you have CMS Chocolate wich is slightly different on the frontend, here´s what I did:
Keep UI theme ( template files, images, js, css, etc. ) in one single repository (i.e. yourcompany/cms-front) and each version in its own branch ( v-vanilla, v-chocolate, v-strawberry)
On your UI Theme you will need to include a simple composer.json file to describe the project
On your CMS project give each version its own branch and force version name match its corresponding layout name.
Reference your front repository in your cms composer.json, I´m assuming We´re talking about a private one here otherwise next lines won´t be necesary.
{
"repositories": [
{
"type": "vcs",
"url": "git#github.com:your-company/cms-front.git"
}
],
"config": {
"github-oauth": {
"github.com": "******"
}
}
}
Add yourcompany/cms-front#dev-$version dependencie to your composer.
composer require yourcompany/cms-front#dev-chocolate
You will need a post-build step to copy from vendor/your-company/cms-$version to your project but this is easy
{
"scripts": {
"sync-theme": [
"cp -r vendor/your-company/cms-front/resources app/resources",
"cp -r vendor/your-company/cms-front/public app/public",
],
"post-install-cmd": [
"#sync-theme"
],
"post-update-cmd": [
"#sync-theme"
]
}
}
Add yourcompany/cms-front#dev-$version on your composer dependencies.
Switch between themes whenever you feel to.

Composer specifying 'in development' packages?

I am working on a project with multiple local git repositories that tie together into a single app. Pretty much like Symfony has different components our app is split up similarly.
My question is, what is the proper way to link to these packages?
I know I can do something like this:
"repositories": [
{ "type": "path", "url": "../another-component" },
{ "type": "path", "url": "../yet-another-component" }
]
This still forces me to do composer install to pull in the packages though. It clones the local git repository that I am using for development whenever I run composer install.
Obviously I do not want to do this every single time I adjust a component that makes up a part of my main app to pull in any changes I have done to repositories that make up my main app repository.
Is there a better way to keep development repositories in sync with each other? Or can I tweak this to get what I want?
I am guessing a lot of developers run into this problem so there must be a well thought out solution for this?
Cheers.
Edit
I have also seen this article which goes over the same concept:
http://tech.vg.no/2014/11/25/using-local-packages-as-composer-dependencies/#comment-522050
The problem is that everytime you make changes to one of the repositories that make up your app you have to run: composer update which is a hassle. I am really looking for a way to just keep them properly in sync.
The above solution works fine, I had to delete my lockfile and clear the composer cache though. Instead of cloning a repository composer will make a symlink and your repositories will be kept in sync.
It might not be advisable to delete your lockfile so if anyone has a better suggestion please post a comment.

How to import project Laravel to other Laravel project

When I worked with Spring MVC in Java , it manage all dependency by Maven and I think with Laravel , all library are managed by Composer. (I'm not sure, cause I'm a newbie in Laravel ^^ )
Now, I have 2 laravel project, one common project and one sub project , in sub project how can I use common project through Composer management ?
As mentioned by Pitchinnate, you can include a local repository via Composer.
You'll want to reference the second repository that the first is dependant upon in the "repositories" section of your composer.json, and then require it.
Ex:
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package"
}
],
"require": {
"my/package": "*#dev"
}
}
This should allow you to link your project and sub-project, if we've understood your question correctly.
Cheers!

Code organization with laravel and several git repositories

I am working on several projects but each one connects to a REST web service.
I've developed the first one using Laravel, and developed a few classes really useful to communicate with the web services.
I would like to start the second one, and of course, reuse the classes developed for the REST connection.
My problem is, my company wants me to use several git directories for the projects, and each one should be uploaded to a different springloops project.
Springloops is a bit like github, you can upload your code using git.
How would you proceed to avoid copy/paste and use the same laravel code but in different projects (and I guess, in different locations)?
I'm not sure I'm really clear, but don't hesitate to ask me for more information if you need to.
Thanks.
How about creating your own Composer package and store it in a separate (private) Git repo? As far as Composer is concerned it's just like any other package, you may want to check out this section of the docs:
Using private repositories
Exactly the same solution allows you to work with your private
repositories at GitHub and BitBucket:
{
"require": {
"vendor/my-private-repo": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "git#bitbucket.org:vendor/my-private-repo.git"
}
]
}
The only requirement is the installation of SSH keys for a git client.

Is this considered a misuse of composer?

Given the following directories at the root of a project:
app/, A combination of static resources and class-mapped project code
src/, Configured to load namespaced PHP code
vendor/, Packages managed by composer.json
Regardless of what framework I happen to be using, would it be correct to make use of the src directory for portable code intended to be usable outside of the project, or is that the role of the vendor directory?
Are there any issues that might arise as a result of using the src directory for code intended to be shared?
This seems like a reasonable design approach. Composer lets you do this by putting your own classes to be autoloaded into a directory and then referring to it in your composer.json . See this question for how: Using Composer's Autoload
However, this won't handle versioning of your code under src/ . If you are going to be separately publishing this, it might be worth learning how to make your library installable through Composer and once you have checked it in to a Git repo somewhere, reference it like this:
"require": {
"me/testlib": "1.0.*"
}
"repositories": [
{
"type": "vcs",
"url": "https://github.com/username/hello-world"
}
]
Sure, then you'll be maintanining multiple source trees, one for your project and one for each library, but that's a good thing right? ("Separation of concerns".)
Your approach looks like a valid one in the general case.
It will however become invalid if the amount of data app or anywhere else outweighs the amount of usable code in src. In other words: If you only host about one shared class in src, and one gigabyte of assets in app that isn't needed for the class, it would be stupid to make this a library.
But in such situation, it would be easy to simply move that class into a composer library on it's own and again include it. Because of autoloading the class will still be there (although the file changed it's location) and be usable in other code. Any any other software requiring the whole bunch of assets will continue to work even if that class is moved.
When moving code into libraries, it might be worth considering that smaller usually is better, but too small is worthless. You don't want to require every single class on it's own - but a reasonable collection of classes with the same topic make an excellent candidate.

Categories