What is the use of Service directory in magento 2 - magento2

Some of the magento vendor module contain folder named as "Service", What is the specific purpose for these directory.
Generally service contract reside in "Api" directory, so already one directory is avaialble then what is the use of additional service directory.

In Magento2, you have a complete freedom, when it comes to naming your folders, as long as you comply with PSR standards.
There are some conventions (as in best practices), but ultimately the name of the folders doesn't really matter...
Commonly used folders are (and better be, as some actions in Magento are based on these conventions, see installation scripts for example):
Api - public interfaces;
Model - model and resource model classes;
Block - block classes;
Helper - helper classes;
Setup - installation scripts;
view - presentation layer files;
etc - configuration files (usually XML and XSD);
etc ...
Please refer to best practices https://devdocs.magento.com/guides/v2.2/ext-best-practices/extension-coding/common-programming-bp.html (there is a version in 2.1 and 2.3 documentation as well), for your own development but keep in mind that not all developers follow (or are even aware of) these guidelines and that - beside the common patterns - you have much more freedom than for M1.

Service directory is not a generic Magento module functional directory.
It is just a custom-created directory and used by that module, and doesn't have a common meaning.
Actually in vendor/magento, there are still many custom created directory inside different default modules, e.g. in module-elasticsearch, there are /Elasticsearch5 and /SearchAdapter directory.

Related

As a dev, do you use .gitignore to ignore everything and purposefully include? Or do you just exclude with it?

We have an internal discussion going here and we are somewhat torn on the best practice for using .gitignore on projects that contain a lot of files (like a CMS).
Method 1
Method 1 would be to purposefully .gitignore all files that come standard with your build. That would generally start like:
# ignore everything in the root except the "wp-content" directory.
!wp-content/
# ignore everything in the "wp-content" directory, except:
# "mu-plugins", "plugins", "themes" directory
wp-content/*
!wp-content/mu-plugins/
!wp-content/plugins/
!wp-content/themes/
# ignore these plugins
wp-content/plugins/hello.php
# ignore specific themes
wp-content/themes/twenty*/
# ignore node dependency directories
node_modules/
# ignore log files and databases
*.log
*.sql
*.sqlite
Some staff members like this approach since if you create something outside of the standard files, for example like a /build folder, then it would automatically be detected for inclusion. However, writing custom theming and plugins require you to add a few layers to this file to "step in" to the folders you want to keep, and generally, the file is a bit messier to read.
Method 2
Method 2 ignores everything, and then you whitelist what you want in the repo. That would look like
# Ignore everything, but all to descend into subdirectories
*
!*/
# root files
!/.gitignore
!/.htaccess.live
!/favicon.ico
!/robots.txt
# theme
!/wp-content/themes/mytheme/**
/wp-content/themes/mytheme/style.css # Ignore Compiled CSS
/wp-content/themes/mytheme/js # Ignore Compiled JS
# plugins
!/wp-content/plugins/my-plugin/**
# deployment resources
!/build/**
Some staff like this since it's cleaner, you have to purposefully add something (which makes accidental adds harder), and it also in effect shows you your .git folder structure.
What is the best practice? Which method do you enjoy and would you recommend doing one over the other?
The second method is the best practice, when it comes to exlude some folder contents of gitignore rules.
It better reflect the following rule:
It is not possible to re-include a file if a parent directory of that file is excluded.
To exclude files (or all files) from a subfolder of an ignored folder f, you would do:
f/**
!f/**/
!f/a/sub/folder/someFile.txt
Meaning: you need to whitelist folders first, before being able to exclude from gitignore files.
It is clearer, shorter (unless you have a large number of folder to whitelist)
What if it is a Joomla install with a large amount of directories and files?
Or what if a core upgrade adds new files or folders
Don't forget you can have multiple gitignore files, one per folder.
That means you can mix and match both approaches.
And you have:
http://gitignore.io/ (which does blacklist when it comes to Joomla application)
github/gitignore (same approach for Joomla)
The ideal .gitignore file, is the one that does not exist.
For some reason, you're deeply intermingling files you want to track via source control, with files you DON'T want to track.
This, I think, is the source of your sadness.
You are mixing git's intended purpose, which is versioning of programmer-edited files, with deployment, which is intended to get the files where they belong in the correct directories.
Your question is not clear, as to whether you think the Wordpress core files should be versioned. I'm assuming not, since that's how you've set up your .gitignore.
Your question is also not clear, as to whether you are deploying a web site, or shipping plugins as a product. Those are both different use cases, and they require different types of versioning. If this is a deployed web site, you SHOULD be versioning Wordpress along with everything else. If you are shipping a plugin or a theme, then you should have a test suite of plenty of different Wordpress versions to test against.
I think your source control system should be set up, solely to track just the plugins/* and/or themes/* files that go into your distribution. Zipping that folder should give you the plugin asset that your customers download.
To debug your plugins, there should be a deploy step in your IDE that copies each of those tracked files, into a Wordpress install at a location you choose. This permits you to more easily test against different Wordpress versions.
You're reducing workflow problems, to trying to choose a .gitignore. Fix the problem at the root by getting the workflow right.

Play Framework - How to maintain configuration files for different environments?

For my Play 2.2/Scala application (built with SBT), I would like to deploy different configuration files depending on the environment I'm deploying to (e.g. to couple a deployment with a particular database server). How does one create different variants of the application's configuration file (conf/application.conf) for different deployment targets? Hopefully variants can be generated from a base version?
What I'm used to from .NET is to have a base configuration file (Web.config), which undergoes a certain transformation depending on the profile one is deploying (e.g. Production). Does one use a similar technique in the Play/Scala world?
Alternative configuration files are covered in Play's documentation quite well in section Specifying alternative configuration file.
In short - in application.conf you place default configuration of your app, and additionally you need to create additional files for you environment(s) ie. life.conf, dev.conf etc. In these files you first need to include application.conf (which will read whole default configuration) and next just overwrite only parts which have to be changed - ie. DB credentials, it could be dev.conf:
include "application.conf"
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:alternative-database-for-dev-testing"
db.default.user=developer
db.default.password="developerpass"
So finally you start your application (after dist) as
./start -Dconfig.resource=dev.conf
or with the Play console
play -Dconfig.resource=dev.conf run
Several tips:
It's good idea to do not place your 'life' DB credentials in default application.conf file, if some dev will forget to include his dev.conf he won't damage the production DB, instead you should put it in prod.conf.
Also these additional configs shouldn't be placed in any VCS (ie. git) repository - creating them directly on target machine (and ignoring in repository) give you sure, that people who shouldn't know the life database credentials won't see it.
It's also possible to use remote alternative config file, which can be useful ie. when you deploying several instances of the same app ie. on several hosts in the cloud.
Each dev can has own config file ie dev_aknuds1.conf, dev_biesior.conf etc, so you can ignore them with one pattern dev_*.conf in repo.
Finally you can just create a shell script (unix) or bat file (Windows) to start using choosen config file like start_dev.sh, run_dev.sh etc. so you won't need to write -Dconfig.resource=... each time

Is it Common to use MEF with a config file for specifying a plugin path?

I have heard that MEF reduces the need for creating config files, but if I have a few different plugin paths that vary depending on the client running the app, is it common and a good idea to have a config file that specifies the correct path. I want to avoid looping through all the DLLs.
Generally people have a well known plugin directory under the where the application is running from, i.e. \Extensions. However that said there isn't any particular reason you cannot do a configuration file for directories or exact extension assemblies.

Zend Framework - many multiple applications

I'm starting new project for my company and it's requiring hosting multiple applications under one domain. Each applications must be accessible by different subdomain (wildcards). One of applications will be control panel for all sub-apps. Creating one multi module application is not an option because of complexity of child applications.
All applications must share common libraries and have access to some app specific ones.
I'm still trying to design directory structure that allow store each applications outside public folder, access them dynamically via subdomain and store some files in public folder for each of them separately.
What I've figured out so far :
Host each application with default ZF dir structure in separate dir outside public. Access to public files is possible by plugin printing files to browser from app public directory (witch is outside domains public dir). Only change to default ZF application is thet there is only one index.php file in public_html that starts requested application based on subdomain.
domain_dir/
controllPanel_app/
application/
configs/
modules/
layouts/
Bootstrap.php
library/
public/
subApps/
exampleSub_app/
application/
library/
public/
anotherExampleSub_app/
application/
...
common/
library/
Zend/
Other/
public_html/
index.php
Is this good idea?
You could do it the way you suggest, but I think it'll be more trouble than it's worth. Zend Framework is designed for modules if needed, but not sub-apps. You'll probably end up with a Zend Router nightmare, or some complicated .htaccess trickery, both of which would be hard to maintain.
Why not have a totally separate Zend Framework application for each subdomain, and another separate app for your control panel? Your company (or you yourself) should be able to reconfigure your HTTP server so each subdomain can have its own Document Root. I do this for my own company, which has a similar situation. (Common control panel app with different public-facing apps for different purposes, as well as having a common library of shared code.)
You can share a common library folder in multiple ways. One is if each app adds this folder to its PHP include_path in each app's index.php or Bootstrap.php file. This is how I prefer to do it. Another way is through symbolic links within each app's library folder.

Ubuntu LAMP with Zend directory structure for web hosting

I have setup the basic LAMP server on Ubuntu 11.10 and had a few questions about directory structure with web hosting. My "requirements" are that I would like to host two websites (ie: www.site1.com and www.site2.com) and also that I would like to use the Zend framework.
Currently, the public folder is /var/www/. Is it common to have a "Projects" folder somewhere containing all of the web application code which generally will consist of the Zend project folders (public, tests, library, etc)?
Where do you "normally" store the Zend framework folder? I was thinking of just storing in in my ~/ directory and creating a symlink from each project's library folder to the Zend library folder. Is this recommended/frowned upon?
I'm new to this and just getting setup, but here is what I had in mind so far:
Create a projects folder in your home directory (~/). Under there, have your different web apps (~/Projects/site1 and ~/Projects/site2). Create a symlink from /var/www/site1 that points to ~/Projects/site1/Public and the same for site2. Setup the virtual hosts file with DocumentRoot set to /var/www/site1 and the same for site2.
Can anyone shed any light on the possible pitfalls of this? Would this be alright to do? Any recommendations? I know there are many versions of how you should setup directories here on SO, but couldn't find any answers that addressed these things specifically, so I apologize if this is a repeat.
Any help is appreciated.
Yes, there are lots of ways to do it, just keep in mind a few things:
The user that owns the HTML/PHP files should not be the same as the user that runs the web server process.
The ZF project files should be outside the web server's document root.
If you make a setup now that's conducive to having multiple developers, you won't have to make big changes later.
I usually do something like make a "site" user with a regular /home/site directory. This keeps the site files separate from your personal files and makes it easier to support multiple admins/devs that might need to login. You can also put this in /opt/site or /usr/local/site or wherever. I like /home because the shell skeleton files are already there and I can easily add SSH keys of the people I want to have access. I'll have something like:
/home/site/
library/
fuel/
geshi/
sencha-touch-2.0.0-gpl/
ZendFramework/
ZendFramework-1.11.10/
ZendFramework-1.11.11/
latest -> ZendFramework-1.11.11
site/
domain1.com/
application/
library/
MyApp/
Zend -> /home/site/library/ZendFramework/latest/library/Zend
public/
scripts/
domain2.com/
application/
library/
MyApp/
Zend -> /home/site/library/ZendFramework/latest/library/Zend
public/
scripts/
Then, your vhost document root settings would point to /home/site/site/domain1.com/public and /home/site/site/domain2.com/public
Directory structures aren't something that there is a right or wrong way to do, lots of people do it in different ways, here is mine with Ubuntu and some CakePHP apps
/srv
/site1/
/app
/webroot
/cache
/tmp
/site2/
/app
/webroot
/cache
/tmp
/share/
/CakePHP
/1.3/
/2.0/
The two main parts of the configuration are done in apache, I set the Document Root of the vhost to the exact location of the webroot to /srv/site1/webroot/, then I put CakePHP in the include path (you could do the same with Zend) by using the php_value include_path ".:/share/cakephp/2.0/lib" in the vhost config.
I do this because it allows me to upgrade CakePHP with maintenance releases easily to all sites, (ie ones that shouldn't break anything) and a new release will warrant a new folder (ie 2.1), and upgrading a site to use it is simply a case of editing the apache config (or .htaccess) and restarting the server.
This also keeps me from having to include any sort of include path in my app (and therefore version control) so it's as portable as possible across different dev/staging setups.
Of course as I said, there isn't one "right" way.