From 235bbfa45140872510865cb528e6d289043188ea Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Sun, 21 Jan 2024 18:00:22 -0500 Subject: [PATCH 1/8] Proofreading --- pages/07.dependency-injection/01.concept/docs.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pages/07.dependency-injection/01.concept/docs.md b/pages/07.dependency-injection/01.concept/docs.md index 48d8d546..b719f174 100644 --- a/pages/07.dependency-injection/01.concept/docs.md +++ b/pages/07.dependency-injection/01.concept/docs.md @@ -32,7 +32,7 @@ $owl = new Owl(); This might seem like a nice, convenient way of packaging things - after all, `Nest` seems like an implementation detail that we shouldn't have to worry about. However, what happens if we come along later with an `ImprovedNest`, and we want our `Owl` to use that instead? -Unfortunately we can't. Our classes `Owl` and `Nest` are what we would call **tightly coupled** - Owls can use Nests and _only_ Nests. Dependency injection solves this problem: +Unfortunately, we can't. Our classes `Owl` and `Nest` are what is called **tightly coupled** - Owls can use Nests and _only_ Nests. Dependency injection solves this problem: ```php class Owl @@ -104,10 +104,10 @@ class Owl } ``` -In the above example, it doesn't matter if `Owl` received a `Nest` or an `ImprovedNest`, or even a `SuperDuperNest`, as long as they all obey the same definition defined by the `NestInterface`. Moreover, the Owl class can confidently call the `getSize` method of the injected `$nest` property, because interface make sure that method is available, no matter which implementation of the `NestInterface` it receive. +In the above example, it doesn't matter if `Owl` received a `Nest` or an `ImprovedNest`, or even a `SuperDuperNest`, as long as they all obey the same definition defined by the `NestInterface`. Moreover, the Owl class can confidently call the `getSize` method of the injected `$nest` property, because the interface makes sure that method is available, no matter which implementation of the `NestInterface` it receives. -Using interfaces to declare what kind of object a class is expected to receive, even if you don't plan to have multiple "nests" types, is a key element in *Autowiring* that we'll see shortly. +Using interfaces to declare what kind of object a class is expected to receive, even if you don't plan to have multiple "nest" types, is a key element in *Autowiring* that we'll see shortly. This is of course a contrived example, but the general strategy of keeping your classes loosely coupled is a good way to make your code more reusable and easily tested. -[notice=tip]You can learn more, and see other examples on the [PHP-DI Website : Understanding Dependency Injection](https://php-di.org/doc/understanding-di.html).[/notice] +[notice=tip]You can learn more, and see other examples, on the [PHP-DI Website : Understanding Dependency Injection](https://php-di.org/doc/understanding-di.html).[/notice] From d809992f960676c8afb5026fbbba583db579b34f Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Sun, 21 Jan 2024 18:36:52 -0500 Subject: [PATCH 2/8] Editing --- .../02.the-di-container/docs.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pages/07.dependency-injection/02.the-di-container/docs.md b/pages/07.dependency-injection/02.the-di-container/docs.md index a5a61646..c6f72c91 100644 --- a/pages/07.dependency-injection/02.the-di-container/docs.md +++ b/pages/07.dependency-injection/02.the-di-container/docs.md @@ -30,7 +30,7 @@ Three main steps are required to create the object: 2. The `$handler` object requires a `$formatter` object, which we inject using `setFormatter()`; 3. The `$handler` object also requires the path to the log file. -This is a lot of code to write just to create one measly object! It would be great if we could somehow encapsulate the creation of the object, but without creating tight couplings by doing that within the object itself. +This is a lot of code to write just to create one measly object! It would be great if we could somehow encapsulate the creation of the object without creating tight couplings within the object itself. This is where the **dependency injection container (DIC)** comes into play. The DIC handles basic management of dependencies, encapsulating their creation into simple callbacks. We will call these callbacks **services**. @@ -39,19 +39,19 @@ This is where the **dependency injection container (DIC)** comes into play. The 1. dependency injection is a method for writing better code 2. a container is a tool to help injecting dependencies -You don't need a container to do dependency injection. However a container can help you. +You don't need a container to do dependency injection. However, a container can make injections easier. [/notice] -UserFrosting uses [_PHP-DI 7_](https://php-di.org) has it's DIC implementation since it provides many powerful features that we rely on: +UserFrosting uses [_PHP-DI 7_](https://php-di.org) as it's DIC implementation since it provides many powerful features that we rely on: -1. It creates dependencies lazily ("on demand"). Any service (and its dependencies) won't be created until the first time I actually try to access them. +1. It creates dependencies lazily ("on demand"). Any service (and its dependencies) won't be created until the first time we access them. 2. Once an object has been created in the container, the same object is returned in each subsequent call to the container. 3. It has the ability to automatically create and inject dependencies. -4. It has powerful Slim 4 integration. +4. It has powerful Slim 4 integration. -Taken together, this means we can define our services without needing to worry about when and where their dependencies are created in our application's lifecycle. +Taken together, we can define our services without needing to worry about when and where their dependencies are created in our application's lifecycle. -[notice=note]When we talk about services, this might bring to mind an anti-pattern called the **Service Locator Pattern**. It is true that the DIC _can_ be used as a service locator, especially if you inject the entire container into your objects. With the exception of Models and a few other types of classes that have a very large number of dependencies, we try to avoid implementing the Service Locator Pattern whenever possible.[/notice] +[notice=note]When we talk about services, this might bring to mind an anti-pattern called the **Service Locator Pattern**. It is true that the DIC _can_ be used as a service locator, especially if you inject the entire container into your objects. With the exception of Models and a few other classes with very large numbers of dependencies, we try to avoid implementing the Service Locator Pattern whenever possible.[/notice] ### Autowiring @@ -72,7 +72,7 @@ class Owl } ``` -When using _PHP-DI_ to create an Owl, the container detects that the constructor takes a `Nest` object (using the [type declarations](http://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)). Without any configuration, **and as long as the constructor argument is properly typed**, PHP-DI will create an `Nest` instance (if it wasn't already created) and pass it as a constructor parameter. The equivalent code would now be : +When using _PHP-DI_ to create an Owl, the container detects that the constructor takes a `Nest` object (using [type declarations](http://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)). Without any configuration, **and as long as the constructor argument is properly typed**, PHP-DI will create an `Nest` instance (if it wasn't already created) and pass it as a constructor parameter. The equivalent code would now be : ```php $owl = $container->get(Owl::class); @@ -86,9 +86,9 @@ It's very simple, doesn't require any configuration, and it just works ! ### Service Providers & Definitions -Sometimes classes might be a bit more complex to instantiate, especially third party ones (eg. the logger object from before). Or you might want to use a different class based on some configuration value. You might also want a class to be replaced by another one (eg. our `ImprovedNest`). In theses cases, autowiring cannot be used. This is where PHP-DI **definition** comes handy. PHP-DI loads the definitions you have written and uses them like instructions on how to create objects. +Sometimes classes might be a bit more complex to instantiate, especially third party ones (eg. the logger object from before). Or you might want to use a different class based on some configuration value. You might also want a class to be replaced by another one (eg. our `ImprovedNest`). In these cases, autowiring cannot be used. This is where PHP-DI **definition** comes handy. PHP-DI loads the definitions you have written and uses them like instructions on how to create objects. -UserFrosting sets up its services through **service provider** classes. Each Sprinkle can define as many service provider it need and register them in their [Recipe](/dependency-injection/adding-services). For example, the Services Provider class for the previous `Logger` example would look like this: +UserFrosting sets up its services through **service provider** classes. Each sprinkle can define as many service providers as it needs and register them in the [Recipe](/dependency-injection/adding-services). For example, the Services Provider class for the previous `Logger` example would look like this: ```php use Monolog\Formatter\LineFormatter; @@ -120,7 +120,7 @@ class LoggerServicesProvider implements ServicesProviderInterface } ``` -This definitions uses [PHP-DI factories](https://php-di.org/doc/php-definitions.html#factories) syntax. From the PHP-DI documentation: +This definition uses the [PHP-DI factories](https://php-di.org/doc/php-definitions.html#factories) syntax. From the PHP-DI documentation: > Factories are PHP callables that return the instance. They allow to easily define objects lazily, i.e. each object will be created only when actually needed (because the callable will be called when actually needed). > @@ -128,9 +128,9 @@ This definitions uses [PHP-DI factories](https://php-di.org/doc/php-definitions. > > Other services can be injected via type-hinting (as long as they are registered in the container or autowiring is enabled). -You'll notice that the callable used to create a `Logger` object takes two parameters, `StreamHandler` and `LineFormatter`. This allows us to inject theses services inside this definition. When `Logger` is created (or injected), both `StreamHandler` and `LineFormatter` will be injected using their own definition. +You'll notice that the callable used to create a `Logger` object takes two parameters: `StreamHandler` and `LineFormatter`. This allows us to inject these services inside the definition. When `Logger` is created (or injected), both `StreamHandler` and `LineFormatter` will be injected using their own definition. -[notice=note]The `LineFormatter` definition is different. It uses the [object syntax](https://php-di.org/doc/php-definitions.html#objects) instead of the _Factories_ syntax.[/notice] +[notice=note]The `LineFormatter` definition is different. It uses the [object syntax](https://php-di.org/doc/php-definitions.html#objects) instead of the _factories_ syntax.[/notice] [notice]You can learn more about PHP Definitions in the [PHP-DI Documentation](https://php-di.org/doc/php-definitions.html#definition-types)[/notice] @@ -165,7 +165,7 @@ return [ ]; ``` -But why are interface really needed? If `ImprovedNest` extends `Nest`, wouldn't the constructor accept an `ImprovedNest` anyway if you typed-hinted against `Nest`? Well, yes... But it won't work the other way around. For example : +But why are interfaces really needed? If `ImprovedNest` extends `Nest`, wouldn't the constructor accept an `ImprovedNest` anyway if you type-hinted against `Nest`? Well, yes... But it won't work the other way around. For example : ```php @@ -197,4 +197,4 @@ $test = new AcceptImprovedNest($nest); // Throws TypeError Exception, Nest is no In most case it's considered "best practice" to type-hint against interfaces, unless you explicitly required an -The next page shows a small list the **default services** that ship with UserFrosting, as well as tips and trick to replace. After that, we talk about how you can **add** your own services, **extend** existing services, or completely **replace** certain services in your own Sprinkle. +The next page shows a small list of the **default services** that ship with UserFrosting, as well as tips for using them. After that, we talk about how you can **add** your own services, **extend** existing services, or completely **replace** certain services in your own sprinkle. From bf71b80cfd49b389a3e534ccc8301b2472910357 Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Mon, 22 Jan 2024 17:13:05 -0500 Subject: [PATCH 3/8] Updated links --- .../03.default-services/docs.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pages/07.dependency-injection/03.default-services/docs.md b/pages/07.dependency-injection/03.default-services/docs.md index b810ac2e..7b7674c1 100644 --- a/pages/07.dependency-injection/03.default-services/docs.md +++ b/pages/07.dependency-injection/03.default-services/docs.md @@ -18,7 +18,7 @@ Third party services are also used directly throughout the code. They can be inj ### `UserFrosting\Alert\AlertStream` -This service handles the [alert message stream](/routes-and-controllers/alert-stream), sometimes known as "flash messages". See [Section 9](/routes-and-controllers/alert-stream) for more information. +This service handles the [alert message stream](/advanced/alert-stream)), sometimes known as "flash messages". (See Chapter 18 for more information.) ### `Illuminate\Cache\Repository as Cache` @@ -64,7 +64,7 @@ Creates a `Throttler` object, which handles [request throttling](/routes-and-con ### `Slim\Interfaces\RouteParserInterface` -See [Chapter 9](/routes-and-controllers) for more information about defining routes and [Slim Documentation](https://www.slimframework.com/docs/v4/objects/routing.html#route-names) on how to use the Route Parser. +See [Chapter 8](/routes-and-controllers) for more information about defining routes and [Slim Documentation](https://www.slimframework.com/docs/v4/objects/routing.html#route-names) on how to use the Route Parser. ### `UserFrosting\Session\Session` @@ -83,13 +83,13 @@ See [Templating with Twig](/templating-with-twig) for more information about Twi ### `UserFrosting\I18n\Translator` -Sets up the `Translator` object (`UserFrosting\I18n\Translator`) for translation, localization, and internationalization of your site's contents. See [Chapter 16](/i18n) for more information. +Sets up the `Translator` object (`UserFrosting\I18n\Translator`) for translation, localization, and internationalization of your site's contents. See [Chapter 17](/i18n) for more information. ### `UserFrosting\UniformResourceLocator\ResourceLocatorInterface` -An instance of our own [Uniform Resource Locator class](https://github.com/userfrosting/framework/tree/develop-5.0/src/UniformResourceLocator#readme), which provides a unified method of accessing Sprinkle entities via [streams](https://webmozart.io/blog/2013/06/19/the-power-of-uniform-resource-location-in-php/). +An instance of our own [Uniform Resource Locator class](https://github.com/userfrosting/framework/tree/develop-5.0/src/UniformResourceLocator#readme), which provides a unified method of accessing Sprinkle entities via streams. -See [Chapter 17](/advanced/locator) for more information. +See [Chapter 18](/advanced/locator) for more information. ### `UserFrosting\Sprinkle\SprinkleManager` @@ -99,25 +99,25 @@ The `SprinkleManager` can be used to get a list of all sprinkles currently loade ### `UserFrosting\Sprinkle\Account\Authenticate\Authenticator` -Creates an instance of `Authenticator`, which handles authenticating and logging in users. See [Chapter 7](/users/user-accounts#authentication-and-authorization) for more information. +Creates an instance of `Authenticator`, which handles authenticating and logging in users. See [Chapter 10](/users/user-accounts#authentication-and-authorization) for more information. ### `UserFrosting\Sprinkle\Account\Authenticate\AuthGuard` -The `AuthGuard` middleware, which is bound to routes that require authentication to access ("protected routes"). See [Chapter 7](/users/user-accounts#authentication-and-authorization) for more information. +The `AuthGuard` middleware, which is bound to routes that require authentication to access ("protected routes"). See [Chapter 10](/users/user-accounts#authentication-and-authorization) for more information. ### `UserFrosting\Sprinkle\Account\Authenticate\GuestGuard` -The `GuestGuard` middleware, which is bound to routes that require a guest (non logged-in user). See [Chapter 7](/users/user-accounts#authentication-and-authorization) for more information. +The `GuestGuard` middleware, which is bound to routes that require a guest (non logged-in user). See [Chapter 10](/users/user-accounts#authentication-and-authorization) for more information. ### `UserFrosting\Sprinkle\Account\Log\AuthLogger` -Monolog `Logger` object for logging detailed information about access control checks. See [Chapter 7](/users/access-control) for more information about access control. Note that access control checks will only be logged if `debug.auth` is set to `true` in the configuration. +Monolog `Logger` object for logging detailed information about access control checks. See [Chapter 10](/users/access-control) for more information about access control. Note that access control checks will only be logged if `debug.auth` is set to `true` in the configuration. ### `UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager` *Associated Interface : `UserFrosting\Sprinkle\Account\Authorize\AuthorizationManagerInterface`* -Creates an instance of `AuthorizationManager`, which handles access control checks via the `checkAccess` method. This service also defines several default access condition callbacks. More information, and a complete list of default access condition callbacks, can be found in [Chapter 7](/users/access-control). +Creates an instance of `AuthorizationManager`, which handles access control checks via the `checkAccess` method. This service also defines several default access condition callbacks. More information, and a complete list of default access condition callbacks, can be found in [Chapter 10](/users/access-control). ### `UserFrosting\Sprinkle\Account\Authenticate\Hasher` From f2da513ec35707974487071de8dc7c6d0e4a30f0 Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Mon, 22 Jan 2024 19:22:34 -0500 Subject: [PATCH 4/8] Edits/proofreading --- .../03.default-services/docs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pages/07.dependency-injection/03.default-services/docs.md b/pages/07.dependency-injection/03.default-services/docs.md index 7b7674c1..9904a1ab 100644 --- a/pages/07.dependency-injection/03.default-services/docs.md +++ b/pages/07.dependency-injection/03.default-services/docs.md @@ -6,11 +6,11 @@ taxonomy: category: docs --- -As mentioned in the last section, each Sprinkle can set up its own services through **services providers**. The [bundled sprinkles](/structure/sprinkles#bundled-sprinkles) set up many services that are essential to UserFrosting's functionality. These services can be found in the `src/ServicesProvider/` subdirectories in each Sprinkle's directory. +As mentioned in the last section, each sprinkle can set up its own services through **service providers**. The [bundled sprinkles](/structure/sprinkles#bundled-sprinkles) set up many services that are essential to UserFrosting's functionality. These services can be found in the `src/ServicesProvider/` subdirectories in each Sprinkle's directory. But this is just the tip of the iceberg, since _Autowiring_ is also used throughout the source code to inject other types of classes pretty much everywhere. -This is a short list of the most important services defined in each Sprinkle. The fully qualified class names are use, so you can easily **inject** them in your controller or other classes. +This is a short list of the most important services defined in each sprinkle. The fully qualified class names are used, so you can easily **inject** them in your controller or other classes. Third party services are also used directly throughout the code. They can be injected using their original fully qualified class name, while still being configured in a sprinkle. @@ -26,7 +26,7 @@ Creates an instance of a Laravel [Cache](https://laravel.com/docs/8.x/cache). Se ### `UserFrosting\Config\Config` -Constructs a `Config` object, which [processes and provides a merged repository for the configuration files](/configuration/config-files) across all loaded Sprinkles. Additionally, it imports the [Dotenv](https://github.com/vlucas/phpdotenv) to allow automatically loading environment variables from `.env` file. +Constructs a `Config` object, which [processes and provides a merged repository for configuration files](/configuration/config-files) across all loaded sprinkles. Additionally, it imports [Dotenv](https://github.com/vlucas/phpdotenv) to allow automatically loading environment variables from `.env` file. The `config` service also builds the `site.uri.public` config variable from the component values specified in the configuration. @@ -64,7 +64,7 @@ Creates a `Throttler` object, which handles [request throttling](/routes-and-con ### `Slim\Interfaces\RouteParserInterface` -See [Chapter 8](/routes-and-controllers) for more information about defining routes and [Slim Documentation](https://www.slimframework.com/docs/v4/objects/routing.html#route-names) on how to use the Route Parser. +See [Chapter 8](/routes-and-controllers) for more information about defining routes, and the [Slim Documentation](https://www.slimframework.com/docs/v4/objects/routing.html#route-names) on how to use the Route Parser. ### `UserFrosting\Session\Session` @@ -99,11 +99,11 @@ The `SprinkleManager` can be used to get a list of all sprinkles currently loade ### `UserFrosting\Sprinkle\Account\Authenticate\Authenticator` -Creates an instance of `Authenticator`, which handles authenticating and logging in users. See [Chapter 10](/users/user-accounts#authentication-and-authorization) for more information. +Creates an instance of `Authenticator`, which handles user authentication and logins. See [Chapter 10](/users/user-accounts#authentication-and-authorization) for more information. ### `UserFrosting\Sprinkle\Account\Authenticate\AuthGuard` -The `AuthGuard` middleware, which is bound to routes that require authentication to access ("protected routes"). See [Chapter 10](/users/user-accounts#authentication-and-authorization) for more information. +The `AuthGuard` middleware, which is bound to routes which require authentication to access ("protected routes"). See [Chapter 10](/users/user-accounts#authentication-and-authorization) for more information. ### `UserFrosting\Sprinkle\Account\Authenticate\GuestGuard` @@ -125,4 +125,4 @@ Creates an instance of `Hasher`, which handles password hashing and validation. ### `UserFrosting\Sprinkle\Account\Log\UserActivityLogger` -Sets up a Monolog logger, which uses `UserFrosting\Sprinkle\Account\Log\UserActivityDatabaseHandler` and `UserFrosting\Sprinkle\Account\Log\UserActivityProcessor` to allow logging of user activities to the `activities` database table. By using Monolog, it makes it easy to swap other storage solutions such as Redis or Elastic Search. +Sets up a Monolog `Logger` object, which uses `UserFrosting\Sprinkle\Account\Log\UserActivityDatabaseHandler` and `UserFrosting\Sprinkle\Account\Log\UserActivityProcessor` to allow logging of user activities to the `activities` database table. Monolog makes it easy to swap to other storage solutions such as Redis or Elastic Search. From a9ae15d7e627f4a4fb42eb1aa877615de03fd130 Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Mon, 22 Jan 2024 19:24:58 -0500 Subject: [PATCH 5/8] Don't repeat section headings --- pages/06.sprinkles/03.recipe/docs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/06.sprinkles/03.recipe/docs.md b/pages/06.sprinkles/03.recipe/docs.md index 6ab1f340..fcfb8c36 100644 --- a/pages/06.sprinkles/03.recipe/docs.md +++ b/pages/06.sprinkles/03.recipe/docs.md @@ -10,7 +10,7 @@ The Sprinkle Recipe dictates how your sprinkle is built, like a blueprint. UserF Each sprinkle **must have** a recipe. It's not possible for a sprinkle to exist without a recipe, as it won't be possible to expose its class and service to the framework. It's possible however to customize other sprinkles, as we'll see later on this page. -## The Sprinkle Recipe +## The `SprinkleRecipe` Interface The Sprinkle Recipe is a simple PHP class that provides standard methods which will be called by services to retrieve information about your sprinkle structure and the class it's registering. Every sprinkle recipe **MUST** implement the `UserFrosting\Sprinkle\SprinkleRecipe` interface. If you started from the [Skeleton](/structure/introduction#the-app-skeleton-your-project-s-template), you already have a basic recipe. From 3d2c59d9d5f4dbdbae0eb4b0424f457ba26445ee Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Mon, 22 Jan 2024 19:27:31 -0500 Subject: [PATCH 6/8] Update links --- pages/07.dependency-injection/04.adding-services/docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/07.dependency-injection/04.adding-services/docs.md b/pages/07.dependency-injection/04.adding-services/docs.md index cde3a259..05b81668 100644 --- a/pages/07.dependency-injection/04.adding-services/docs.md +++ b/pages/07.dependency-injection/04.adding-services/docs.md @@ -8,7 +8,7 @@ taxonomy: You'll probably want to create your own services to modularize certain aspects of your own project. For example, if your application needs to interact with some third-party API like Google Maps, you might create a `MapBuilder` class that encapsulates all of that functionality. This is a cleaner and more manageable alternative to simply stuffing all of your code directly into your controller classes. -If you want to use a single instance of `MapBuilder` throughout your application, you'll probably end up defining it as a service. To do this, you'll need to create a new `MapBuilderService` class in your site Sprinkle and register it in your Sprinkle [recipe](/sprinkles/recipe#getservices). +If you want to use a single instance of `MapBuilder` throughout your application, you'll probably end up defining it as a service. To do this, you'll need to create a new `MapBuilderService` class in your site Sprinkle and register it in your Sprinkle [recipe](/sprinkles/recipe#services). You can actually create one big service provider for all your services, but it's best to create different provider classes for each services. This makes it easier to test and debug each of your services. It also makes things easier if you need to extend or disable a service in another sprinkle down the road. With this setup, each service reside in it's own provider class instead of the global `ServiceProvider` class. For example : @@ -92,4 +92,4 @@ class MyApp implements SprinkleRecipe } ``` -That's it! Behind the scenes, UserFrosting will register every definition from each service provider with the DI container, following the sprinkle [dependency tree](/sprinkles/recipe#getsprinkles) during the [application lifecycle](/advanced/application-lifecycle). +That's it! Behind the scenes, UserFrosting will register every definition from each service provider with the DI container, following the sprinkle [dependency tree](/sprinkles/recipe#dependent-sprinkles) during the [application lifecycle](/advanced/application-lifecycle). From 291726c686c687fb6e7e7c83555482f912adef09 Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Tue, 23 Jan 2024 22:11:05 -0500 Subject: [PATCH 7/8] Edits and proofreading --- .../07.dependency-injection/04.adding-services/docs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pages/07.dependency-injection/04.adding-services/docs.md b/pages/07.dependency-injection/04.adding-services/docs.md index 05b81668..01f79fa5 100644 --- a/pages/07.dependency-injection/04.adding-services/docs.md +++ b/pages/07.dependency-injection/04.adding-services/docs.md @@ -8,9 +8,9 @@ taxonomy: You'll probably want to create your own services to modularize certain aspects of your own project. For example, if your application needs to interact with some third-party API like Google Maps, you might create a `MapBuilder` class that encapsulates all of that functionality. This is a cleaner and more manageable alternative to simply stuffing all of your code directly into your controller classes. -If you want to use a single instance of `MapBuilder` throughout your application, you'll probably end up defining it as a service. To do this, you'll need to create a new `MapBuilderService` class in your site Sprinkle and register it in your Sprinkle [recipe](/sprinkles/recipe#services). +If you want to use a single instance of `MapBuilder` throughout your application, you'll probably end up defining it as a service. To do this, you'll need to create a new `MapBuilderService` class in your site sprinkle and register it in your [Sprinkle Recipe](/sprinkles/recipe#services). -You can actually create one big service provider for all your services, but it's best to create different provider classes for each services. This makes it easier to test and debug each of your services. It also makes things easier if you need to extend or disable a service in another sprinkle down the road. With this setup, each service reside in it's own provider class instead of the global `ServiceProvider` class. For example : +You can actually create one big service provider for all your services, but it's best to create different provider classes for each service. This makes it easier to test and debug each of your services. It also makes things easier if you need to extend or disable a service in another sprinkle down the road. With this setup, each service resides in its own provider class instead of the global `ServiceProvider` class. For example : ``` app @@ -23,7 +23,7 @@ app ### Create your service -First, we'll create the service class. This class **must** implement the `UserFrosting\ServicesProvider\ServicesProviderInterface` interface. It must contain the `register` method, which return an array of [service definitions](/dependency-injection/the-di-container#service-providers-definitions). +First, we'll create the service class. This class **must** implement the `UserFrosting\ServicesProvider\ServicesProviderInterface` interface. It must contain the `register` method, which returns an array of [service definitions](/dependency-injection/the-di-container#service-providers-definitions). **app/src/ServicesProvider/MapBuilderService.php**: @@ -62,9 +62,9 @@ class MapBuilderService implements ServicesProviderInterface [notice=tip]You'll notice that we've added `use UserFrosting\Sprinkle\Site\GoogleMaps\MapBuilder;` to the top of the file. This means that we don't have to use the fully qualified class name (with the entire namespace) every time we want to refer to the `MapBuilder` class.[/notice] -### Register your Service +### Register your service -The next step is to tell UserFrosting to load your service in your [recipe](/sprinkles/recipe#getservices). To do so, you only need to list all the services providers you want to automatically register inside the `$servicesproviders` property of your sprinkle class : +The next step is to tell UserFrosting to load your service in your [Sprinkle Recipe](/sprinkles/recipe#getservices). To do so, you only need to list all the service providers you want to automatically register inside the `$getServices` property of your sprinkle class : **app/src/MyApp.php** : ```php From 8f8dbcc996714a94ebe9f006c6bffa9de73d1288 Mon Sep 17 00:00:00 2001 From: StrykeSlammerII Date: Tue, 23 Jan 2024 22:17:21 -0500 Subject: [PATCH 8/8] Fixed a link, edits and proofreading --- .../05.extending-services/docs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pages/07.dependency-injection/05.extending-services/docs.md b/pages/07.dependency-injection/05.extending-services/docs.md index 85e7aa76..51719723 100644 --- a/pages/07.dependency-injection/05.extending-services/docs.md +++ b/pages/07.dependency-injection/05.extending-services/docs.md @@ -1,18 +1,18 @@ --- title: Extending Existing Services metadata: - description: You may extend UserFrosting's default services for additional functionality, or define completely new services in your Sprinkles. + description: You may extend UserFrosting's default services for additional functionality, or define completely new services in your sprinkles. taxonomy: category: docs --- -PHP-DI allows us to extend services that were defined previously, for example in another Sprinkle, using [decorators]([/doc/definition-overriding.html#decorators](https://php-di.org/doc/definition-overriding.html#decorators)) +PHP-DI allows us to extend services that were defined previously, for example in another sprinkle, using [decorators](https://php-di.org/doc/definition-overriding.html#decorators). -Most of the default services that UserFrosting defines can be overridden in your Sprinkle. However, some higher level service cannot be extended since they have already been invoked before the SprinkleManager can load the Sprinkles. These services are mostly in the [UserFrosting Framework](/structure/framework). +Most of the default services that UserFrosting defines can be overridden in your sprinkle. However, some higher level services cannot be extended since they have already been invoked before the SprinkleManager can load the sprinkles. These services are mostly in the [UserFrosting Framework](/structure/framework). ## Overriding Existing Services -Extending a service is done using the same callback used to **register** one, except said callback is registered with the `\DI\decorate` method instead of a factory for example. +Extending a service is done using the same callback used to **register** one, except said callback is registered with the `\DI\decorate` method (instead of a factory or other technique). For example, if you want to extend the `ExceptionHandlerMiddleware` service to register a new handler : @@ -31,4 +31,4 @@ public function register(): array The first parameter of the callable is the instance returned by the previous definition (i.e. the one we wish to decorate), the second parameter is the container. -[notice=note]When extending a service, UserFrosting will always apply the extension **on top** of the previously defined service. The service are defined following the sprinkle dependency tree. It's important to keep in mind you might not always received the `core` sprinkle definition, for example, and that your own extension can be overwritten down the road by a subsequent sprinkle.[/notice] +[notice=note]When extending a service, UserFrosting will always apply the extension **on top** of the previously defined service. The service is defined following the sprinkle dependency tree. It's important to keep in mind you might not always receive the `core` sprinkle definition, for example, and that your own extension can be overwritten down the road by a subsequent sprinkle.[/notice]