Download the PHP package seanmorris/ids without Composer
On this page you can find all versions of the php package seanmorris/ids. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package ids
SeanMorris/Ids v00.0.0
/ eye dee ess / • The PHP + Docker Framework
The Ids library provides general domain-primitives for developing web based applications. Routing, requests, modeling configuration, logging, sessions, and database access are all abstracted behind simple, expressive interfaces to efficient and powerful code.
To prevent unexpected behavior, the system is set to die on all errors down to E_NOTICE
, excluding E_DEPRECATED
errors generated from the vendor directory.
The project is made to run in docker but doesn't require it. It can be included in any composer project, and used in part or in whole easily.
The philosophy of the Ids project is headlined by security, speed and easy of use, in that order.
View the docs at docs.ids.seanmorr.is
Dependencies
expand
* Composer * Docker * Docker Compose * GNU Make * Git * Linux or Compatible OS * PHP * SimpleTest * Minikube (required for kubernetes targets only)Installing
expand
Include Ids in your project with: Install Ids globally for access to the `idilic` cli tool: Add composer's global `vendor/bin` to your PATH by adding this to your `~/.bashrc`.Creating a New Ids Project
expand
Create a new project with composer, enter the directory and start php, apache & mysql: Thats it! The companion package that provides a template for new projects can be found here: https://github.com/seanmorris/ids-projectDev Tools
expand
The `dev` build target provides facilities for connecting to xdebug and graylog. ### XDebug XDebug is built into the `dev` images by default. You can configure it by setting `XDEBUG_CONFIG_` environment variables in `.env.dev`. By default it will attempt to connect to port 9000 on `${DHOST_IP}`, which is the machine runing the project. ### Apt Cache *Rebuild your images offline* Build the project with `+aptcache` with an internet connection to populate your cache. ... to be continued ### GrayLog `\SeanMorris\Ids\Logger\Gelf` provides a simple interface to graylog. Just add it to the `IDS_LOGGERS_` environment variable to enable it. So long as there is a graylog server available , it will send all logs that meet the verbosity threshold. The default graylog config for the `dev` target looks like: This package comes with a default GELF TCP input in its graylog config backup. You can run `make graylog-restore` after starting graylog for the first time to create the input. The graylog config can be backed up and restored with the following commands: Graylog can be started and stopped with the following commands: Some usersIdilic CLI
expand
Ids comes with the `idilic` command when installed globally with composer. When executed, it will ascend through the current path looking for another project including Ids. When it finds it, it will attach to that project and utilize its facilities. If it encounters a local `idilic` pass-thru in the project directory, it will hand control to the docker environment where execution will continue. Run `idilic help` to see actions exposed by any installed packages.Multistaging / Environment Targets
expand
### base, prod, dev, and test By default Ids provides 4 build targets: base, prod, dev, and test. Each exposes different ports, so they may run without conflict in parallel. * **base** exposes no ports and builds **without** require-dev. * **prod** exposes port 80 (configurable by `IDS_EXPOSE_HTTP`) and port 443* ( configurable by `IDS_EXPOSE_HTTPS` ) and builds **without** require-dev. * **test** exposes port 2021 (configurable by `IDS_EXPOSE_HTTP`) and port 3031 ( `IDS_EXPOSE_SQL` ) and builds **with** require-dev. * **dev** exposes port 2020 ( configurable by `IDS_EXPOSE_HTTP` ) and port 3030 ( `IDS_EXPOSE_SQL` ) and builds **with** require-dev. \*Not yet implemented. ### Switching Targets The system will use the TARGET environment variable to decide which build target to use. If youre on the BASH shell simply run one of the following commands to set the target for the context of a single command: * `make @base start` * `make @dev build` * `make @test test` * `make @prod push-images` If you don't feek like typing `@target` for every command, you can ask the system to remember a target with: * `make stay@base` * `make stay@dev` * `make stay@test` * `make stay@prod` ### Extending Environments Additional targets may be specified by creating a new `infra/compose/[TARGET].yml` in your project. Build this file as you'd build any other docker-compose file. Then create a new `.env.[TARGET]` file in `config/`. Add your defaults here. If you need some target specific build steps. then add a `FROM base as TARGET` section to any docker files in `infra/docker` that are relevant to that build target. You can expand on any existing build target, you're not limited to extending `base`.Build
expand
The project may be built with `make`. Debian users can get this tool by running `apt-get install build-essential`. The build process also requires `docker` and `docker-compose`. `minikube` is required only for kubernetes testing. The default build target is `base`. run `make stay@dev` or `make stay@test` to switch to the development/testing target. You can use @TARGET at the beginning of any make command to use the target for just that command. Docker & docker-compose are available here: * https://docs.docker.com/install/ * https://docs.docker.com/compose/install/Start / Stop / Restart
expand
Make sure to set a target with `make stay@target` before issuing any commands. Alternatively you can run commands in the form `make @target command`.Images & Tags
expand
Autotagging / Autopublishing / Git Hooks
expand
Register git hooks with `make hooks`. Image tags are generated automatically on build based on the date, current git tag (falls back to commit hash). The master branch will generate: * repository/project:gitTag-target * repository/project:date-target * repository/project:latest-target Branches other than master will generate: * repository/project:gitTag-target-branch * repository/project:date-target-branch * repository/project:latest-target-branch Images will be built on `git commit` and pushed on `git push` if the current branch appears in the project root `.publishing` file in the form: `BRANCH:TARGET`. For example this file would push images for prod & test when `git push` is run for the master branch:Available Images
expand
Docker images for seanmorris/ids.idilic & seanmorris/ids.server for targets `base`, `dev`, and `test` are available for use & extension on DockerHub: * idilic https://hub.docker.com/repository/docker/seanmorris/ids.idilic * server https://hub.docker.com/repository/docker/seanmorris/ids.server Pull from the cli with: or extend in a dockerfile with one of the following: (it is not recommended to use `latest` in `FROM`)Service Switches
expand
Additional services can be included when running Ids. Simply add +toolname to your @target when issing a make command, and the necessary composer files will be included in the comtext of your command. For example, to start the system with graylog in dev mode: Or inotify Or bothTemplating
expand
*This ain't your granpappy's makefile.* GNU Make has a distinct and powerful syntax. It borrows, or in some instances outright uses the underlying bash engine to allow a user to define complex build steps and track the relationships between them to ensure everything is up to date. Make allows for recursive variable expansion, conditionals, loops, and even calls out to the shell. This syntax is no longer limted to the Makefile. Simply put the extension `*.idstmp.*` *before* your existing file extension. Ids will look for these files in all subdirectories of the prohect and rebuild them on startup. The resulting file will have the extension `*.___gen.*` where the `*.idstmp.*` is in the source file. The resulting files should be excluded from version control, as they may contain artifacts from one target that should not exist in another. For example: *infra/docker/aptcache.idstmp.dockerfile* starts off with the following line: Varibles are not normally allowed in the `FROM` section of dockerfile, preprocessed by make before it is used. So long as the file extenstion begins with `.idstmp.`, we can count on a `.___gen.` file being produced. This allows us to keep all the images and containers synced to one base image. The follwing lines from the end of the file show how one can use the shell to track who generated the file and when: See [Functions for Transforming Text](https://www.gnu.org/software/make/manual/html_node/Functions.html#Functions) for more information.Configuration / Environment Variables / Secrets
expand
### Loading Settings Settings may be provided in environment variables, .env files, or yml files. #### Environment Variable & Target Files The following files may be created/modified to configure the system. When the project is built, restarted, etc, they will be checked for modification, and re-built to the root of the projct if need be. The files generated to the root of the project should not be committed to version control. * `config/.env` - Should not be committed to version control. Contains configuration that applies to the system regardles of the system's target. * `config/.env.default` - Should be committed to version control. Contains non-secret configurations file and blank/dfault values for variables to be set in `config/.env`. * `config/.env_TARGET` - Should not be committed to version control. Contains configuration based the system's target. * `config/.env_TARGET.default` - Should be committed to version control. Contains non-secret configurations file and blank/dfault values for variables to be set in `config/.env_TARGET`. The values set will be read according to the following precedence (higher takes precedence over lower): * `.env_TARGET` * `.env_TARGET.default` * `.env` * `.env.default` Environment variables to be used in configuration should have the the prefix `IDS_`. An environment variable with the name IDS_SOME_VAR and IDS_SOME_OTHERVAR would be accessible within the system with: ### Configuration Objects They'd also both be accessible as an object, which can be iterated: ### Configuration Arrays Arrays can be created by adding an underscore to the end of the environment variable name. The value will be split on whitespace. Whitespace will be preserved if the value is quotes: Quotes can be escaped by doubling: ### Hostname & Port based configuration Hostname specific environment variables are prefixed with an extra underscore: `IDS__`. Dots and other non-word charaters in the hostname are placed by a single underscore, **except for the hyhpen which is replaced by 3 underscores.** Another double underscore finishes the hostname, and the variable name comes next. The above environment variables could be overridden for example.com with: `IDS__EXAMPLE_COM__SOME_VAR` and `IDS__EXAMPLE_COM__SOME_OTHERVAR`. They would be accessed in the same way as above: Example.com could override the variables by port number if they wanted to change some behavior based on whether the user was on SSL. Adding another double underscore between the hostname and the variable name allows us to do that: `IDS__EXAMPLE_COM__80__SOME_VAR` and `IDS__EXAMPLE_COM__80_SOME_OTHERVAR` for HTTP and `IDS__EXAMPLE_COM__443__SOME_VAR` and `IDS__EXAMPLE_COM__443_SOME_OTHERVAR` for HTTPS. Again, nothing changes in way they are accessed. The code reads them in the same way: ### Non-Secret Config Default values for environment variables that are **non-secrets**, (and thus may be pushed to version control) may be set in `config/.env`. Target specific variables may be set in `config/.env.[TARGET]`. **DO NOT PUT SECRETS SUCH AS PASSWORDS HERE.** These files will be checked into version control. These files will be used to generate the final .env files in the root of the project when the project is built or started. ### Disposable Secrets If you need a quick random value to use in the build process (ie when creating a MYSQL password), make sure to add the key to the relevant .env file, but leave the value blank. Add the key name to the `.entropy` file in the root of your project in the form: `CONFIG_KEY:ENTROPY_KEY`. `CONFIG_KEY` is the name of your configuration value, and `ENTROPY_KEY` is an arbitrary string that allows you to re-use the same random value between different configuration keys. When the project starts, the .env files will be generated to the root of the project if they do not exist already, or if the existing ones are empty. Any keys present in the `.entropy` file will be set to a random 32 character string. This is how the schema name, username, and password are generated for the mysql server for the `make test` command when if the current `TARGET` is `test`. run `TARGET=test idilic info` to see an example of this. ### Normal Secrets So long as the .env files exist, and are not empty, the system will not attempt to regenerate them, so any secrets could in theory be added here, in place. This works fine for development, but for production it is recomended that secrets be stored in environtment variables. Values from environment variables and .env files may accessd via PHP's `getenv()`. Ensure you've set the relevent values in the `environment` section of the target's docker-compose file if you chose not to add the value to a .env file. ### Json/Yaml Configuration #### Settings Json/Yaml files may be provided in the `config/` directory, under a directory named `hostname/` or `hostname;port/`, where `hostname` and `port` are the domain and port you expect requests to come in on. The file should then be named `settings.json` or `settings.yml`. A directory named `_;80` or `;80` will match only for requests on port 80 regardless of the hostname. A directory named `_;`, `_`, or ';' may be provided as a fallback if no others match. **NOTE** If any yml config file is loaded, the system stops there and does not look for others. Host or port specific yml files will not be merged with more general wild card ones. #### Defaults Default, non-secret values may be provided in a file named `settings.defaults.yml` or `settings.defaults.json`. Defaults are the same as settings except they're stored in version control. Defaults are loaded by the same rules as standard settings files. Once a singe defaults file is found no more will be loaded. Settings and Defaults files do not need to be loaded at the same level of generality. `settings.yml` may be found in `_;80` and settings.defaults.yml may be found in `hostname` or vice versa. Settings always take precedence over defaults. Environment variables from the shell or .env files take precedence over yml files. to be continued...Schema Diffing & Patching
expand
Ensure you've installed the `idilic` cli tool from the start of the document. Use the following commands to manage your database schema. `idilic storeSchema [PACKAGE]` - Store the current schema. `idilic applySchema [PACKAGE]` - Apply the stored schema. `idilic applySchemas` - Apply the stored schema for all installed packages. The schema will be stored in `data/global/schema.json`.Routing
expand
Modeling / ORM
expand
### Defining models * Properties * Selectors * Column wrappers * Behavior ### Loading Models Model load methods are dynamically generated with names in the form of: `VERB [Flat] [Submodel|Record] [By SELECTOR]([...$args])` #### Verbs * get - Gets an array of models. * getOne - Gets a single model. * load - Returns a callback that gets an array of models. * loadOne - Alias of getOne. * generate - Returns a callback that produces a Generator of models. * count - Returns a count of models. * report - Return an (optionally) aggregated result set as a 2d array. #### Modifiers * Flat - Don't join child models, even if specified in selector (parent class tables are still joined) * Submodel - Include any subclass of a given model in result set (May not include all tables!); * Record - Load records but skip initialization logic (before/afterRead methods). #### SelectorsLogging
expand
Logs can be written from anywhere in the system by calling a function coresponging to the desied level of verbosity. There are 6 levels of verbosity available. Ids will write logs to a file or handle specified by the `IDS_LOG` config: The current level of verbosity can be configured with the `IDS_LOGLEVEL` variable. **NOTE**: If `LOGLEVEL` is set to `trace`, **every single log entry** will be accompanied by a stack trace. This can fill a disk quickly. Use with caution! ### ANSI Colors Logging comes with ANSI color turned on by default. Set the following config to disable it if thats causing problems for whatever you're using to read the logs: ### Censoring Logs Set the `IDS_LOGCENSOR_` array in your config to define an array of values that should not appear in log files. If these values are found as function arguments, array keys, or object properties, they will be logged as `* censored *` rather than their actual value. The default censor filter is: You can test censor filters. Issuing the following command will output your database settings, with no censorship applied: Adding -vv to the idilic command will force it to print its logs to `STDERR` (without verbosity checks). We can drop the original output of the command as follows to declutter the terminal: We can also extract the original output with: ### Redirecting / Forcing CLI Logs Logging can be forced on the command line with `-v` and `-vv`. * `-v` will print any logs within the current verbosity thesholds to `STDERR`. * `-vv` will print any logs REGARDLESS of verbosity thesholds to `STDERR`. Logs of individual commands can be redirected to files or handles with `2>`. If you're more interested in the logs than the output, you can discard the output with: ### Graylog Logs may be sent to Graylog by providing a custom log handler in the config ### Custom Loggers Custom loggers may created by implemeting the `\SeanMorris\Ids\Logger` interface. Add them to the `IDS_LOGGERS_` array to activate them:Debugging
expand
Linking Packages
expand
Some features require foreknowledge of what packages, files, and classes are present. Scanning for this list every time one of those features is used would slow things to a crawl. Build this index with the following commands:Testing
expand
File Access
expand
Migrations*
expand
to be completedAsset Management
expand
to be completedHTTP API*
expand
to be completedIPC / AMPQ*
expand
to be completedImplmenting Idilic CLI Commands
expand
Idilic commands can be run from the CLI in the form `idilic command` or `idilic Vendor/Package command`. Note that on the CLI package names can be separated by a forward slash (`/`). This is done to prevent the user from being forced to remember to escape backslashes (`\`). Run `idilic help` to get a list of available idilic commands. New commands can be implemented by adding a route class named `RootRoute` under the namespace `Vendor\Package\Idilic\Route` like so:Dependency Injection
expand
Some classes provide injection constructors. They'll take one or more classes as an argument and in return will give you a new class to work with. For example, the `SeanMorris\Ids\Collection` class provides a method that will return a new subclass that will work only with the given type: In this example, DatetimeCollection does not exist until afte the `::of()` method completes, but PHP will still allow us to access `::CLASS` on it. We also alias the DatetimeCollection class with `use` BEFORE it exists. This prevents it from inheriting the `Author\Package` namespace in this scenario, although it is not necessary. ### Creating Injectables Creating a new injectable class from scratch is easy. You can either inherit from an existing class that uses the `SeanMorris\Ids\Injectable` trait, or create an entirely new class from scratch with the following construct: **NOTE:** If you override the constructor, you must either call `parent::__construct()` or `$this->initInjections();` in your subclass contructor to ensure your injections are ready when your object are instantiated. You could now use `new $injectableClass` to instantiate a class with very little functionality. The problem here is that you can't inherit from an anonymous class in PHP. To solve this problem we can pass a second parameter to `::inject()` to name the class: ### Class Promotion The last example showed something called *class promotion*, this simply allows us to take an anonymous class and "promote" it to a named class to that other parts of the system can refer to it by name. There are two ways to promote a class: With the `Injectable` trait: Or with the `Loader` class: ### Defining Injections In `::inject()`'s' first parameter, we can define any default injections we'd like our class to have, to facilitate situations where we'd want it to have access to a default set of behaviors we can override. You can now access the injections as a static property of the newly created class: Since the injections are represented by static properties, injectables are accessible just fine in the static scope: You can continue to create further subclasses that may or may not override the default injections: ### Subclassing existing/default injections If the existing injection is a static property, you can simply acesss it and call `::inject()` on it to create a subclass of the existing injection: Or you could promote the class and extend it directly: If the existing injection is a static property, you can simply acesss it and call `::inject()` on it to create an injected subclass: ### Creating injectables out of existing classes Any class that can be extended can become injectable: ### Factories, Singletons & Injectable Methods Behaviors may be dynamically provided as injections by wrapping closure with a simple class to let the system know how to treat it. The methods are wrapped by classes so they may participate in the `Loader` system. See *Global Injections* for more information on that topic. #### Injected Methods The WrappeMethod class allows you to pass a method along that will not be called by the system, allowing it to be used in code. `RankIterator` implements the following method in such a way that a map method can be injected: The new iterator class with mapping behavior can be created like so: #### Factory Methods Factory methods may be provided in a similar manner. ### Singleton Methods Singletons may be loaded in a similar manner. A method wrapped by `SingletonMethod` will be called only once and its return value used as the provided injection for all cases. Singletons provided as static properties will be instatiated on definition, rather than on property access. ### Global injections & \\___\\... namespaces Injections can be defined globally so that classes can just pick up on them and go. Using the `\___\...` namespace, we can set up places where injections can be defined globally. You can also use the `\Author\Project\___\...` namespace. For example, if the `AwesomeLogger` class from above were defined like this: An injection can be defined globally in the `ids.boot.php` file in the `source/` directory of the project. This can be overridden as the root project's boot file will be executed last. #### Overriding global injections Global injections may only be overridden **before** they are used in code. This does not count access to `::CLASS` or `use` statments that import classes from other namespaces. #### Fallback global injections Sometimes you might want to allow injections to be overriden for the whole of the system or perhaps some of its parts. If you want this behavior as well as a fallback to a default the following pattern will handle that. In this example, any part of the system may ask for "Red Paint", "Blue Paint", or "*Just whatever* Paint". They might not get the color they asked for, but they will get paint. This would allow us to override all instances where "Paint" is injected. This would allow us to override only instances where "Red Paint" is injected.Sessions
expand
to be completedexpand
Themes & Frontends
expand
to be completedMake Commands
expand
Run these from the project root to build and control the project infrastructure. * `make build` `make b` - Build the project * `make env` `make e` - Print the project's environment config. * `make test` `make t`- Run tests. * `make test` `make t`- Remove the generated configs,* *even if they have been altered.** * `make start` `make s`- Start the project services. * `make start-fg` `make sf`- Start the project services, hold control of the terminal and stream output. * `make start-bg` `make sb`- Start the project services, hold control of the terminal and stream output. * `make restart-fg` `make rf` - Restart the project services, hold control of the terminal and stream output. * `make restart-bg` `make rb`- Restart the project services, hold control of the terminal and stream output. * `make stop` `make d`- Stop the project services. * `make stop-all` `make da`- Stop the project services, including any that no longer appear in the compose file. * `make kill` `make k`- Immediately kill the project services. * `make nuke` `make nk`* - Immediately kill all containers on the host. Not yet implemented. * `make current-tag` `ct`- Output the project tag for the current target & branch. * `make list-tags` `make lt`- List image tags for the current target & branch. * `make list-images` `make li`- List images for the current target & branch. * `make push-images` `make psi`- List images for the current target & branch. * `make pull-images` `make pli`- List images for the current target & branch. * `make hooks` - Initialize git hooks. * `make composer-install` `make ci`- Install composer packages. * `make composer-update` `make co`- Update composer packages. * `make composer-dump-autoload` `make cda`- Regenerate and dump composer autoload files.. * `make npm install PKG="[PACKAGE]"` `make ni`- Run `npm install` inside the project. * `make bash` `make sh`- Get a bash prompt to an `idilic` container. * `make run CMD="SERVICE [COMMAND]"` `make r`- Run a command in a service container.SeanMorris/Ids
Copyright 2011-2022 Sean Morris
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
built by sean @ Mon Feb 20 09:13:03 AM EST 2023