Update 2024-08-21 11:08:12

This commit is contained in:
Robot 2024-08-21 23:08:24 +02:00
parent 8559278b19
commit 29e38023c0
Signed by: Robot
GPG Key ID: 14DECD44E7E1BB95
214 changed files with 27531 additions and 2292 deletions

View File

@ -31,10 +31,10 @@ This repository contains an index (see below) of all the approved powers within
- **abstract class Factory** | [Details](src/d910d8b8-4c23-4f3e-8cda-438f2d2bd7ac) | [Code](src/d910d8b8-4c23-4f3e-8cda-438f2d2bd7ac/code.php) | [Settings](src/d910d8b8-4c23-4f3e-8cda-438f2d2bd7ac/settings.json) | SPK: `Super---d910d8b8_4c23_4f3e_8cda_438f2d2bd7ac---Power`
- **final class Component** | [Details](src/e2472b22-a329-44d8-b4a2-ae3ba99e17a0) | [Code](src/e2472b22-a329-44d8-b4a2-ae3ba99e17a0/code.php) | [Settings](src/e2472b22-a329-44d8-b4a2-ae3ba99e17a0/settings.json) | SPK: `Super---e2472b22_a329_44d8_b4a2_ae3ba99e17a0---Power`
- **final class JoomlaPower** | [Details](src/3730a000-ab64-477d-8b0f-70eaf71b517a) | [Code](src/3730a000-ab64-477d-8b0f-70eaf71b517a/code.php) | [Settings](src/3730a000-ab64-477d-8b0f-70eaf71b517a/settings.json) | SPK: `Super---3730a000_ab64_477d_8b0f_70eaf71b517a---Power`
- **final class Language** | [Details](src/8eee7df5-2775-41a9-9372-c46c5939a252) | [Code](src/8eee7df5-2775-41a9-9372-c46c5939a252/code.php) | [Settings](src/8eee7df5-2775-41a9-9372-c46c5939a252/settings.json) | SPK: `Super---8eee7df5_2775_41a9_9372_c46c5939a252---Power`
- **class Config** | [Details](src/fa4bf18e-301e-42e3-91fb-6e0096c07adc) | [Code](src/fa4bf18e-301e-42e3-91fb-6e0096c07adc/code.php) | [Settings](src/fa4bf18e-301e-42e3-91fb-6e0096c07adc/settings.json) | SPK: `Super---fa4bf18e_301e_42e3_91fb_6e0096c07adc---Power`
- **class Customcode** | [Details](src/313b43c4-98c3-4f62-9177-2d73ec8eba31) | [Code](src/313b43c4-98c3-4f62-9177-2d73ec8eba31/code.php) | [Settings](src/313b43c4-98c3-4f62-9177-2d73ec8eba31/settings.json) | SPK: `Super---313b43c4_98c3_4f62_9177_2d73ec8eba31---Power`
- **class Field** | [Details](src/d7ba2d5d-10b6-470d-978d-9f91ea65ee75) | [Code](src/d7ba2d5d-10b6-470d-978d-9f91ea65ee75/code.php) | [Settings](src/d7ba2d5d-10b6-470d-978d-9f91ea65ee75/settings.json) | SPK: `Super---d7ba2d5d_10b6_470d_978d_9f91ea65ee75---Power`
- **class Language** | [Details](src/8eee7df5-2775-41a9-9372-c46c5939a252) | [Code](src/8eee7df5-2775-41a9-9372-c46c5939a252/code.php) | [Settings](src/8eee7df5-2775-41a9-9372-c46c5939a252/settings.json) | SPK: `Super---8eee7df5_2775_41a9_9372_c46c5939a252---Power`
- **class Placeholder** | [Details](src/06453ada-e370-49f0-b262-e3f5a8ed0c2c) | [Code](src/06453ada-e370-49f0-b262-e3f5a8ed0c2c/code.php) | [Settings](src/06453ada-e370-49f0-b262-e3f5a8ed0c2c/settings.json) | SPK: `Super---06453ada_e370_49f0_b262_e3f5a8ed0c2c---Power`
- **class Power** | [Details](src/b836c1b1-b6b1-44f7-b8a2-9a763a4185b1) | [Code](src/b836c1b1-b6b1-44f7-b8a2-9a763a4185b1/code.php) | [Settings](src/b836c1b1-b6b1-44f7-b8a2-9a763a4185b1/settings.json) | SPK: `Super---b836c1b1_b6b1_44f7_b8a2_9a763a4185b1---Power`
- **class Registry** | [Details](src/e5d9804f-0eb0-4ee9-b406-ad4e8cdbc1f6) | [Code](src/e5d9804f-0eb0-4ee9-b406-ad4e8cdbc1f6/code.php) | [Settings](src/e5d9804f-0eb0-4ee9-b406-ad4e8cdbc1f6/settings.json) | SPK: `Super---e5d9804f_0eb0_4ee9_b406_ad4e8cdbc1f6---Power`
@ -136,6 +136,7 @@ This repository contains an index (see below) of all the approved powers within
- **final class ModelMediumField** | [Details](src/b0b26749-5e2c-4b56-8982-48172f2531fa) | [Code](src/b0b26749-5e2c-4b56-8982-48172f2531fa/code.php) | [Settings](src/b0b26749-5e2c-4b56-8982-48172f2531fa/settings.json) | SPK: `Super---b0b26749_5e2c_4b56_8982_48172f2531fa---Power`
- **final class ModelWhmcsField** | [Details](src/28cac2bb-df04-454f-b4d6-923b573eb94e) | [Code](src/28cac2bb-df04-454f-b4d6-923b573eb94e/code.php) | [Settings](src/28cac2bb-df04-454f-b4d6-923b573eb94e/settings.json) | SPK: `Super---28cac2bb_df04_454f_b4d6_923b573eb94e---Power`
- **final class MovedPublishingFields** | [Details](src/9cdff2af-bd1b-452f-810e-d034b9720d2a) | [Code](src/9cdff2af-bd1b-452f-810e-d034b9720d2a/code.php) | [Settings](src/9cdff2af-bd1b-452f-810e-d034b9720d2a/settings.json) | SPK: `Super---9cdff2af_bd1b_452f_810e_d034b9720d2a---Power`
- **final class Multilingual** | [Details](src/a8c6158a-6fd2-476b-a5ea-c81f1ecd2356) | [Code](src/a8c6158a-6fd2-476b-a5ea-c81f1ecd2356/code.php) | [Settings](src/a8c6158a-6fd2-476b-a5ea-c81f1ecd2356/settings.json) | SPK: `Super---a8c6158a_6fd2_476b_a5ea_c81f1ecd2356---Power`
- **final class MysqlTableSetting** | [Details](src/9ff6d6cd-afea-4f15-a67b-fd132d386989) | [Code](src/9ff6d6cd-afea-4f15-a67b-fd132d386989/code.php) | [Settings](src/9ff6d6cd-afea-4f15-a67b-fd132d386989/settings.json) | SPK: `Super---9ff6d6cd_afea_4f15_a67b_fd132d386989---Power`
- **final class NewPublishingFields** | [Details](src/0f141480-afe6-41fb-996c-2a4e566a2f0d) | [Code](src/0f141480-afe6-41fb-996c-2a4e566a2f0d/code.php) | [Settings](src/0f141480-afe6-41fb-996c-2a4e566a2f0d/settings.json) | SPK: `Super---0f141480_afe6_41fb_996c_2a4e566a2f0d---Power`
- **final class OrderZero** | [Details](src/66b7b5f8-60d6-427a-9f8c-84c11a3d6780) | [Code](src/66b7b5f8-60d6-427a-9f8c-84c11a3d6780/code.php) | [Settings](src/66b7b5f8-60d6-427a-9f8c-84c11a3d6780/settings.json) | SPK: `Super---66b7b5f8_60d6_427a_9f8c_84c11a3d6780---Power`
@ -205,6 +206,7 @@ This repository contains an index (see below) of all the approved powers within
- **final class FieldString** | [Details](src/44d039b9-d293-481b-b560-23a6e7a63962) | [Code](src/44d039b9-d293-481b-b560-23a6e7a63962/code.php) | [Settings](src/44d039b9-d293-481b-b560-23a6e7a63962/settings.json) | SPK: `Super---44d039b9_d293_481b_b560_23a6e7a63962---Power`
- **final class FieldXML** | [Details](src/ac691a05-5630-4002-b166-dedec3fb0fcb) | [Code](src/ac691a05-5630-4002-b166-dedec3fb0fcb/code.php) | [Settings](src/ac691a05-5630-4002-b166-dedec3fb0fcb/settings.json) | SPK: `Super---ac691a05_5630_4002_b166_dedec3fb0fcb---Power`
- **final class FieldsetDynamic** | [Details](src/b5986fab-17ca-4236-8c0c-81ebd2bb82ba) | [Code](src/b5986fab-17ca-4236-8c0c-81ebd2bb82ba/code.php) | [Settings](src/b5986fab-17ca-4236-8c0c-81ebd2bb82ba/settings.json) | SPK: `Super---b5986fab_17ca_4236_8c0c_81ebd2bb82ba---Power`
- **final class FieldsetExtension** | [Details](src/23f459a4-7c2a-4cbf-b0a6-8a11954140a9) | [Code](src/23f459a4-7c2a-4cbf-b0a6-8a11954140a9/code.php) | [Settings](src/23f459a4-7c2a-4cbf-b0a6-8a11954140a9/settings.json) | SPK: `Super---23f459a4_7c2a_4cbf_b0a6_8a11954140a9---Power`
- **final class FieldsetString** | [Details](src/05448890-e324-41a0-b6db-d804bfc241cc) | [Code](src/05448890-e324-41a0-b6db-d804bfc241cc/code.php) | [Settings](src/05448890-e324-41a0-b6db-d804bfc241cc/settings.json) | SPK: `Super---05448890_e324_41a0_b6db_d804bfc241cc---Power`
- **final class FieldsetXML** | [Details](src/79739667-72c6-4576-9830-7b1eb92e4791) | [Code](src/79739667-72c6-4576-9830-7b1eb92e4791/code.php) | [Settings](src/79739667-72c6-4576-9830-7b1eb92e4791/settings.json) | SPK: `Super---79739667_72c6_4576_9830_7b1eb92e4791---Power`
- **final class Layout** | [Details](src/a0f032db-2242-41df-8e4a-5e9e6f88201d) | [Code](src/a0f032db-2242-41df-8e4a-5e9e6f88201d/code.php) | [Settings](src/a0f032db-2242-41df-8e4a-5e9e6f88201d/settings.json) | SPK: `Super---a0f032db_2242_41df_8e4a_5e9e6f88201d---Power`
@ -251,6 +253,7 @@ This repository contains an index (see below) of all the approved powers within
- **interface HistoryInterface** | [Details](src/4325745f-da1f-4d4d-a591-3189fe8c06e5) | [Code](src/4325745f-da1f-4d4d-a591-3189fe8c06e5/code.php) | [Settings](src/4325745f-da1f-4d4d-a591-3189fe8c06e5/settings.json) | SPK: `Super---4325745f_da1f_4d4d_a591_3189fe8c06e5---Power`
- **interface LanguageInterface** | [Details](src/d6592c9b-93a6-41b3-83c7-c43a0a80cb83) | [Code](src/d6592c9b-93a6-41b3-83c7-c43a0a80cb83/code.php) | [Settings](src/d6592c9b-93a6-41b3-83c7-c43a0a80cb83/settings.json) | SPK: `Super---d6592c9b_93a6_41b3_83c7_c43a0a80cb83---Power`
- **interface PlaceholderInterface** | [Details](src/a6cdd935-c038-4a54-8446-54bed87f003c) | [Code](src/a6cdd935-c038-4a54-8446-54bed87f003c/code.php) | [Settings](src/a6cdd935-c038-4a54-8446-54bed87f003c/settings.json) | SPK: `Super---a6cdd935_c038_4a54_8446_54bed87f003c---Power`
- **interface PluginDataInterface** | [Details](src/8cc85656-a925-4a46-a49b-83c72167fd6a) | [Code](src/8cc85656-a925-4a46-a49b-83c72167fd6a/code.php) | [Settings](src/8cc85656-a925-4a46-a49b-83c72167fd6a/settings.json) | SPK: `Super---8cc85656_a925_4a46_a49b_83c72167fd6a---Power`
- **interface PowerInterface** | [Details](src/1133c2d7-ba7e-4c95-8cde-01f084d04682) | [Code](src/1133c2d7-ba7e-4c95-8cde-01f084d04682/code.php) | [Settings](src/1133c2d7-ba7e-4c95-8cde-01f084d04682/settings.json) | SPK: `Super---1133c2d7_ba7e_4c95_8cde_01f084d04682---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\JoomlaFive](#vdm-joomla-componentbuilder-compiler-joomlafive)
@ -275,14 +278,16 @@ This repository contains an index (see below) of all the approved powers within
- **class Data** | [Details](src/cb11e8d9-69c2-4095-831c-59908ea402e7) | [Code](src/cb11e8d9-69c2-4095-831c-59908ea402e7/code.php) | [Settings](src/cb11e8d9-69c2-4095-831c-59908ea402e7/settings.json) | SPK: `Super---cb11e8d9_69c2_4095_831c_59908ea402e7---Power`
- **class Structure** | [Details](src/071c7cff-4c88-4b80-bd99-066c572dcb71) | [Code](src/071c7cff-4c88-4b80-bd99-066c572dcb71/code.php) | [Settings](src/071c7cff-4c88-4b80-bd99-066c572dcb71/settings.json) | SPK: `Super---071c7cff_4c88_4b80_bd99_066c572dcb71---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin](#vdm-joomla-componentbuilder-compiler-joomlaplugin)
- **class Data** | [Details](src/766a9524-37df-4604-91a7-b98a6150ee26) | [Code](src/766a9524-37df-4604-91a7-b98a6150ee26/code.php) | [Settings](src/766a9524-37df-4604-91a7-b98a6150ee26/settings.json) | SPK: `Super---766a9524_37df_4604_91a7_b98a6150ee26---Power`
- **class Structure** | [Details](src/a900b836-f2eb-4f13-8f28-b7cac839c7ff) | [Code](src/a900b836-f2eb-4f13-8f28-b7cac839c7ff/code.php) | [Settings](src/a900b836-f2eb-4f13-8f28-b7cac839c7ff/settings.json) | SPK: `Super---a900b836_f2eb_4f13_8f28_b7cac839c7ff---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Language](#vdm-joomla-componentbuilder-compiler-language)
- **class Extractor** | [Details](src/d33b9278-c409-4aec-a047-b72f56712391) | [Code](src/d33b9278-c409-4aec-a047-b72f56712391/code.php) | [Settings](src/d33b9278-c409-4aec-a047-b72f56712391/settings.json) | SPK: `Super---d33b9278_c409_4aec_a047_b72f56712391---Power`
- **class Fieldset** | [Details](src/4ad7020e-39ab-49ba-977b-de6084944502) | [Code](src/4ad7020e-39ab-49ba-977b-de6084944502/code.php) | [Settings](src/4ad7020e-39ab-49ba-977b-de6084944502/settings.json) | SPK: `Super---4ad7020e_39ab_49ba_977b_de6084944502---Power`
- **final class Extractor** | [Details](src/d33b9278-c409-4aec-a047-b72f56712391) | [Code](src/d33b9278-c409-4aec-a047-b72f56712391/code.php) | [Settings](src/d33b9278-c409-4aec-a047-b72f56712391/settings.json) | SPK: `Super---d33b9278_c409_4aec_a047_b72f56712391---Power`
- **final class Fieldset** | [Details](src/4ad7020e-39ab-49ba-977b-de6084944502) | [Code](src/4ad7020e-39ab-49ba-977b-de6084944502/code.php) | [Settings](src/4ad7020e-39ab-49ba-977b-de6084944502/settings.json) | SPK: `Super---4ad7020e_39ab_49ba_977b_de6084944502---Power`
- **final class Insert** | [Details](src/1d051a2f-0691-45a8-b3d9-d0c1adcd73bc) | [Code](src/1d051a2f-0691-45a8-b3d9-d0c1adcd73bc/code.php) | [Settings](src/1d051a2f-0691-45a8-b3d9-d0c1adcd73bc/settings.json) | SPK: `Super---1d051a2f_0691_45a8_b3d9_d0c1adcd73bc---Power`
- **final class Multilingual** | [Details](src/263f0227-3cc2-4a88-9818-edb20081c30c) | [Code](src/263f0227-3cc2-4a88-9818-edb20081c30c/code.php) | [Settings](src/263f0227-3cc2-4a88-9818-edb20081c30c/settings.json) | SPK: `Super---263f0227_3cc2_4a88_9818_edb20081c30c---Power`
- **final class Purge** | [Details](src/0b0e574c-aab4-4eaf-96d8-d7210d8ed93e) | [Code](src/0b0e574c-aab4-4eaf-96d8-d7210d8ed93e/code.php) | [Settings](src/0b0e574c-aab4-4eaf-96d8-d7210d8ed93e/settings.json) | SPK: `Super---0b0e574c_aab4_4eaf_96d8_d7210d8ed93e---Power`
- **final class Set** | [Details](src/058cfcd7-1f84-4cc6-8bcc-7672f316881d) | [Code](src/058cfcd7-1f84-4cc6-8bcc-7672f316881d/code.php) | [Settings](src/058cfcd7-1f84-4cc6-8bcc-7672f316881d/settings.json) | SPK: `Super---058cfcd7_1f84_4cc6_8bcc_7672f316881d---Power`
- **final class Translation** | [Details](src/344d36be-3949-4848-8cb0-e3d3d9d05c36) | [Code](src/344d36be-3949-4848-8cb0-e3d3d9d05c36/code.php) | [Settings](src/344d36be-3949-4848-8cb0-e3d3d9d05c36/settings.json) | SPK: `Super---344d36be_3949_4848_8cb0_e3d3d9d05c36---Power`
- **final class Update** | [Details](src/375543cd-5f2a-4893-982e-a73eaa55360d) | [Code](src/375543cd-5f2a-4893-982e-a73eaa55360d/code.php) | [Settings](src/375543cd-5f2a-4893-982e-a73eaa55360d/settings.json) | SPK: `Super---375543cd_5f2a_4893_982e_a73eaa55360d---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Library](#vdm-joomla-componentbuilder-compiler-library)
- **class Data** | [Details](src/7175c1cd-2071-4cd7-b499-23881e168c3f) | [Code](src/7175c1cd-2071-4cd7-b499-23881e168c3f/code.php) | [Settings](src/7175c1cd-2071-4cd7-b499-23881e168c3f/settings.json) | SPK: `Super---7175c1cd_2071_4cd7_b499_23881e168c3f---Power`
@ -332,9 +337,9 @@ This repository contains an index (see below) of all the approved powers within
- **class Reverse** | [Details](src/ca111518-e47c-4049-b1b2-cb010f23866f) | [Code](src/ca111518-e47c-4049-b1b2-cb010f23866f/code.php) | [Settings](src/ca111518-e47c-4049-b1b2-cb010f23866f/settings.json) | SPK: `Super---ca111518_e47c_4049_b1b2_cb010f23866f---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Power](#vdm-joomla-componentbuilder-compiler-power)
- **final class Infusion** | [Details](src/0419081e-4cb3-4c65-8c6a-ffe941fb0f1c) | [Code](src/0419081e-4cb3-4c65-8c6a-ffe941fb0f1c/code.php) | [Settings](src/0419081e-4cb3-4c65-8c6a-ffe941fb0f1c/settings.json) | SPK: `Super---0419081e_4cb3_4c65_8c6a_ffe941fb0f1c---Power`
- **class Autoloader** | [Details](src/6e64917c-d687-4ef3-a655-811319f5a81e) | [Code](src/6e64917c-d687-4ef3-a655-811319f5a81e/code.php) | [Settings](src/6e64917c-d687-4ef3-a655-811319f5a81e/settings.json) | SPK: `Super---6e64917c_d687_4ef3_a655_811319f5a81e---Power`
- **class Extractor** | [Details](src/eeb03266-22fd-45bb-953a-961bb6be3a54) | [Code](src/eeb03266-22fd-45bb-953a-961bb6be3a54/code.php) | [Settings](src/eeb03266-22fd-45bb-953a-961bb6be3a54/settings.json) | SPK: `Super---eeb03266_22fd_45bb_953a_961bb6be3a54---Power`
- **class Infusion** | [Details](src/0419081e-4cb3-4c65-8c6a-ffe941fb0f1c) | [Code](src/0419081e-4cb3-4c65-8c6a-ffe941fb0f1c/code.php) | [Settings](src/0419081e-4cb3-4c65-8c6a-ffe941fb0f1c/settings.json) | SPK: `Super---0419081e_4cb3_4c65_8c6a_ffe941fb0f1c---Power`
- **class Injector** | [Details](src/763d137c-42bc-4282-98d8-cc5c0654985f) | [Code](src/763d137c-42bc-4282-98d8-cc5c0654985f/code.php) | [Settings](src/763d137c-42bc-4282-98d8-cc5c0654985f/settings.json) | SPK: `Super---763d137c_42bc_4282_98d8_cc5c0654985f---Power`
- **class Structure** | [Details](src/324566de-0f7d-4b6e-9caf-8424d55013ae) | [Code](src/324566de-0f7d-4b6e-9caf-8424d55013ae/code.php) | [Settings](src/324566de-0f7d-4b6e-9caf-8424d55013ae/settings.json) | SPK: `Super---324566de_0f7d_4b6e_9caf_8424d55013ae---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Service](#vdm-joomla-componentbuilder-compiler-service)
@ -342,6 +347,7 @@ This repository contains an index (see below) of all the approved powers within
- **class Adminview** | [Details](src/2dd1289a-4000-43cc-8c62-77ff32de56bf) | [Code](src/2dd1289a-4000-43cc-8c62-77ff32de56bf/code.php) | [Settings](src/2dd1289a-4000-43cc-8c62-77ff32de56bf/settings.json) | SPK: `Super---2dd1289a_4000_43cc_8c62_77ff32de56bf---Power`
- **class ArchitectureController** | [Details](src/56ba30f5-a5c4-4c4c-be6f-a56f7f9cbc60) | [Code](src/56ba30f5-a5c4-4c4c-be6f-a56f7f9cbc60/code.php) | [Settings](src/56ba30f5-a5c4-4c4c-be6f-a56f7f9cbc60/settings.json) | SPK: `Super---56ba30f5_a5c4_4c4c_be6f_a56f7f9cbc60---Power`
- **class ArchitectureModel** | [Details](src/bbd36fbf-d905-47e8-8e67-9ea6ec734712) | [Code](src/bbd36fbf-d905-47e8-8e67-9ea6ec734712/code.php) | [Settings](src/bbd36fbf-d905-47e8-8e67-9ea6ec734712/settings.json) | SPK: `Super---bbd36fbf_d905_47e8_8e67_9ea6ec734712---Power`
- **class ArchitecturePlugin** | [Details](src/98ac432d-df19-4c40-bb12-8104ea4362c8) | [Code](src/98ac432d-df19-4c40-bb12-8104ea4362c8/code.php) | [Settings](src/98ac432d-df19-4c40-bb12-8104ea4362c8/settings.json) | SPK: `Super---98ac432d_df19_4c40_bb12_8104ea4362c8---Power`
- **class BuilderAJ** | [Details](src/c7230c8c-ea88-4d8d-8c53-6136133195b7) | [Code](src/c7230c8c-ea88-4d8d-8c53-6136133195b7/code.php) | [Settings](src/c7230c8c-ea88-4d8d-8c53-6136133195b7/settings.json) | SPK: `Super---c7230c8c_ea88_4d8d_8c53_6136133195b7---Power`
- **class BuilderLZ** | [Details](src/2c76c06e-a371-4b73-9fbe-b4d9b4df55d7) | [Code](src/2c76c06e-a371-4b73-9fbe-b4d9b4df55d7/code.php) | [Settings](src/2c76c06e-a371-4b73-9fbe-b4d9b4df55d7/settings.json) | SPK: `Super---2c76c06e_a371_4b73_9fbe_b4d9b4df55d7---Power`
- **class Compiler** | [Details](src/ea5ed06e-72ae-4906-9167-1cc0fa32fe69) | [Code](src/ea5ed06e-72ae-4906-9167-1cc0fa32fe69/code.php) | [Settings](src/ea5ed06e-72ae-4906-9167-1cc0fa32fe69/settings.json) | SPK: `Super---ea5ed06e_72ae_4906_9167_1cc0fa32fe69---Power`
@ -384,6 +390,10 @@ This repository contains an index (see below) of all the approved powers within
- **class Pathfix** | [Details](src/cdc9b06d-8333-4fa7-ab4d-b810dd90f95f) | [Code](src/cdc9b06d-8333-4fa7-ab4d-b810dd90f95f/code.php) | [Settings](src/cdc9b06d-8333-4fa7-ab4d-b810dd90f95f/settings.json) | SPK: `Super---cdc9b06d_8333_4fa7_ab4d_b810dd90f95f---Power`
- **class Paths** | [Details](src/6f20369a-8536-4870-a1a3-cda254c939c8) | [Code](src/6f20369a-8536-4870-a1a3-cda254c939c8/code.php) | [Settings](src/6f20369a-8536-4870-a1a3-cda254c939c8/settings.json) | SPK: `Super---6f20369a_8536_4870_a1a3_cda254c939c8---Power`
- **class Structure** | [Details](src/1efdded5-d6c8-452c-8f37-0374483a7b3f) | [Code](src/1efdded5-d6c8-452c-8f37-0374483a7b3f/code.php) | [Settings](src/1efdded5-d6c8-452c-8f37-0374483a7b3f/settings.json) | SPK: `Super---1efdded5_d6c8_452c_8f37_0374483a7b3f---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Interfaces\Plugin](#vdm-joomla-componentbuilder-interfaces-plugin)
- **interface InfusionInterface** | [Details](src/40e17114-2193-4a61-9233-47b5f4193665) | [Code](src/40e17114-2193-4a61-9233-47b5f4193665/code.php) | [Settings](src/40e17114-2193-4a61-9233-47b5f4193665/settings.json) | SPK: `Super---40e17114_2193_4a61_9233_47b5f4193665---Power`
- **interface StructureInterface** | [Details](src/ef66b17c-ffae-414a-9067-20a63ba2bec5) | [Code](src/ef66b17c-ffae-414a-9067-20a63ba2bec5/code.php) | [Settings](src/ef66b17c-ffae-414a-9067-20a63ba2bec5/settings.json) | SPK: `Super---ef66b17c_ffae_414a_9067_20a63ba2bec5---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\JoomlaPower\Readme](#vdm-joomla-componentbuilder-joomlapower-readme)
- **final class Item** | [Details](src/fcbd0dd7-1f26-472e-abd3-56265f4999f2) | [Code](src/fcbd0dd7-1f26-472e-abd3-56265f4999f2/code.php) | [Settings](src/fcbd0dd7-1f26-472e-abd3-56265f4999f2/settings.json) | SPK: `Super---fcbd0dd7_1f26_472e_abd3_56265f4999f2---Power`
@ -410,6 +420,7 @@ This repository contains an index (see below) of all the approved powers within
- **Namespace**: [VDM\Joomla\Componentbuilder\Power\Remote](#vdm-joomla-componentbuilder-power-remote)
- **final class Get** | [Details](src/3ab0eba9-f37b-4b37-aec1-2e78067f2aff) | [Code](src/3ab0eba9-f37b-4b37-aec1-2e78067f2aff/code.php) | [Settings](src/3ab0eba9-f37b-4b37-aec1-2e78067f2aff/settings.json) | SPK: `Super---3ab0eba9_f37b_4b37_aec1_2e78067f2aff---Power`
- **final class Set** | [Details](src/caf559ee-8337-4f07-9e4a-394d4e06afdc) | [Code](src/caf559ee-8337-4f07-9e4a-394d4e06afdc/code.php) | [Settings](src/caf559ee-8337-4f07-9e4a-394d4e06afdc/settings.json) | SPK: `Super---caf559ee_8337_4f07_9e4a_394d4e06afdc---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Power\Service](#vdm-joomla-componentbuilder-power-service)
- **class Generator** | [Details](src/a7101bbc-3c81-4b52-a4aa-522291f7594b) | [Code](src/a7101bbc-3c81-4b52-a4aa-522291f7594b/code.php) | [Settings](src/a7101bbc-3c81-4b52-a4aa-522291f7594b/settings.json) | SPK: `Super---a7101bbc_3c81_4b52_a4aa_522291f7594b---Power`
@ -482,6 +493,21 @@ This repository contains an index (see below) of all the approved powers within
- **interface ExtractorInterface** | [Details](src/c159425c-51f9-4a15-af99-f2d0c6d7aae8) | [Code](src/c159425c-51f9-4a15-af99-f2d0c6d7aae8/code.php) | [Settings](src/c159425c-51f9-4a15-af99-f2d0c6d7aae8/settings.json) | SPK: `Super---c159425c_51f9_4a15_af99_f2d0c6d7aae8---Power`
- **interface InjectorInterface** | [Details](src/e923311a-4058-4e81-9f67-5956fd0c627c) | [Code](src/e923311a-4058-4e81-9f67-5956fd0c627c/code.php) | [Settings](src/e923311a-4058-4e81-9f67-5956fd0c627c/settings.json) | SPK: `Super---e923311a_4058_4e81_9f67_5956fd0c627c---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive](#vdm-joomla-componentbuilder-compiler-joomlaplugin-joomlafive)
- **final class Data** | [Details](src/174f5c9c-5e03-4261-94ca-279ca76c710d) | [Code](src/174f5c9c-5e03-4261-94ca-279ca76c710d/code.php) | [Settings](src/174f5c9c-5e03-4261-94ca-279ca76c710d/settings.json) | SPK: `Super---174f5c9c_5e03_4261_94ca_279ca76c710d---Power`
- **final class Infusion** | [Details](src/7f75b300-534c-4f63-a368-6f4abc4cea58) | [Code](src/7f75b300-534c-4f63-a368-6f4abc4cea58/code.php) | [Settings](src/7f75b300-534c-4f63-a368-6f4abc4cea58/settings.json) | SPK: `Super---7f75b300_534c_4f63_a368_6f4abc4cea58---Power`
- **class Structure** | [Details](src/d05c22be-9641-47fb-8a7b-063c43e7f1bf) | [Code](src/d05c22be-9641-47fb-8a7b-063c43e7f1bf/code.php) | [Settings](src/d05c22be-9641-47fb-8a7b-063c43e7f1bf/settings.json) | SPK: `Super---d05c22be_9641_47fb_8a7b_063c43e7f1bf---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour](#vdm-joomla-componentbuilder-compiler-joomlaplugin-joomlafour)
- **final class Data** | [Details](src/361e08c0-5916-4b77-b6a2-c16a769bbc40) | [Code](src/361e08c0-5916-4b77-b6a2-c16a769bbc40/code.php) | [Settings](src/361e08c0-5916-4b77-b6a2-c16a769bbc40/settings.json) | SPK: `Super---361e08c0_5916_4b77_b6a2_c16a769bbc40---Power`
- **final class Infusion** | [Details](src/84fe58db-d64d-42c6-9b41-f80bcff34c7f) | [Code](src/84fe58db-d64d-42c6-9b41-f80bcff34c7f/code.php) | [Settings](src/84fe58db-d64d-42c6-9b41-f80bcff34c7f/settings.json) | SPK: `Super---84fe58db_d64d_42c6_9b41_f80bcff34c7f---Power`
- **class Structure** | [Details](src/34daa4c8-45c3-4249-baa3-1bedf8ed3ebc) | [Code](src/34daa4c8-45c3-4249-baa3-1bedf8ed3ebc/code.php) | [Settings](src/34daa4c8-45c3-4249-baa3-1bedf8ed3ebc/settings.json) | SPK: `Super---34daa4c8_45c3_4249_baa3_1bedf8ed3ebc---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree](#vdm-joomla-componentbuilder-compiler-joomlaplugin-joomlathree)
- **final class Data** | [Details](src/766a9524-37df-4604-91a7-b98a6150ee26) | [Code](src/766a9524-37df-4604-91a7-b98a6150ee26/code.php) | [Settings](src/766a9524-37df-4604-91a7-b98a6150ee26/settings.json) | SPK: `Super---766a9524_37df_4604_91a7_b98a6150ee26---Power`
- **final class Infusion** | [Details](src/03b75302-98ba-47ac-859f-1f49b738f66c) | [Code](src/03b75302-98ba-47ac-859f-1f49b738f66c/code.php) | [Settings](src/03b75302-98ba-47ac-859f-1f49b738f66c/settings.json) | SPK: `Super---03b75302_98ba_47ac_859f_1f49b738f66c---Power`
- **class Structure** | [Details](src/a900b836-f2eb-4f13-8f28-b7cac839c7ff) | [Code](src/a900b836-f2eb-4f13-8f28-b7cac839c7ff/code.php) | [Settings](src/a900b836-f2eb-4f13-8f28-b7cac839c7ff/settings.json) | SPK: `Super---a900b836_f2eb_4f13_8f28_b7cac839c7ff---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Model\JoomlaFive](#vdm-joomla-componentbuilder-compiler-model-joomlafive)
- **final class Customtabs** | [Details](src/92cc3144-1d3d-45b2-b49f-c7d356950033) | [Code](src/92cc3144-1d3d-45b2-b49f-c7d356950033/code.php) | [Settings](src/92cc3144-1d3d-45b2-b49f-c7d356950033/settings.json) | SPK: `Super---92cc3144_1d3d_45b2_b49f_c7d356950033---Power`
@ -491,6 +517,9 @@ This repository contains an index (see below) of all the approved powers within
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Model\JoomlaThree](#vdm-joomla-componentbuilder-compiler-model-joomlathree)
- **final class Customtabs** | [Details](src/fa8c1125-d370-4cb6-a7ff-eb32193c198c) | [Code](src/fa8c1125-d370-4cb6-a7ff-eb32193c198c/code.php) | [Settings](src/fa8c1125-d370-4cb6-a7ff-eb32193c198c/settings.json) | SPK: `Super---fa8c1125_d370_4cb6_a7ff_eb32193c198c---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin](#vdm-joomla-componentbuilder-interfaces-architecture-plugin)
- **interface MainXMLInterface** | [Details](src/97177ca9-a51a-4d24-81e1-8747b6e7d76c) | [Code](src/97177ca9-a51a-4d24-81e1-8747b6e7d76c/code.php) | [Settings](src/97177ca9-a51a-4d24-81e1-8747b6e7d76c/settings.json) | SPK: `Super---97177ca9_a51a_4d24_81e1_8747b6e7d76c---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Controller](#vdm-joomla-componentbuilder-compiler-architecture-joomlafive-controller)
- **final class AllowAdd** | [Details](src/005fce79-1b62-4a93-8d5e-8c89fee1afc6) | [Code](src/005fce79-1b62-4a93-8d5e-8c89fee1afc6/code.php) | [Settings](src/005fce79-1b62-4a93-8d5e-8c89fee1afc6/settings.json) | SPK: `Super---005fce79_1b62_4a93_8d5e_8c89fee1afc6---Power`
@ -500,6 +529,11 @@ This repository contains an index (see below) of all the approved powers within
- **final class CanDelete** | [Details](src/34df20ec-67db-4e7e-be61-fb94d360c408) | [Code](src/34df20ec-67db-4e7e-be61-fb94d360c408/code.php) | [Settings](src/34df20ec-67db-4e7e-be61-fb94d360c408/settings.json) | SPK: `Super---34df20ec_67db_4e7e_be61_fb94d360c408---Power`
- **final class CanEditState** | [Details](src/318a98a3-bb6f-42cb-a000-352d4c848b51) | [Code](src/318a98a3-bb6f-42cb-a000-352d4c848b51/code.php) | [Settings](src/318a98a3-bb6f-42cb-a000-352d4c848b51/settings.json) | SPK: `Super---318a98a3_bb6f_42cb_a000_352d4c848b51---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin](#vdm-joomla-componentbuilder-compiler-architecture-joomlafive-plugin)
- **final class Extension** | [Details](src/28c8eed4-58cf-4d40-9053-ad77b6edfa9d) | [Code](src/28c8eed4-58cf-4d40-9053-ad77b6edfa9d/code.php) | [Settings](src/28c8eed4-58cf-4d40-9053-ad77b6edfa9d/settings.json) | SPK: `Super---28c8eed4_58cf_4d40_9053_ad77b6edfa9d---Power`
- **final class MainXML** | [Details](src/a7124f78-21c5-400e-984d-4c5463cb2315) | [Code](src/a7124f78-21c5-400e-984d-4c5463cb2315/code.php) | [Settings](src/a7124f78-21c5-400e-984d-4c5463cb2315/settings.json) | SPK: `Super---a7124f78_21c5_400e_984d_4c5463cb2315---Power`
- **final class Provider** | [Details](src/63865266-62e0-40bd-820c-e95449d12982) | [Code](src/63865266-62e0-40bd-820c-e95449d12982/code.php) | [Settings](src/63865266-62e0-40bd-820c-e95449d12982/settings.json) | SPK: `Super---63865266_62e0_40bd_820c_e95449d12982---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Controller](#vdm-joomla-componentbuilder-compiler-architecture-joomlafour-controller)
- **final class AllowAdd** | [Details](src/425b1107-933d-4436-87ac-63540ec101c5) | [Code](src/425b1107-933d-4436-87ac-63540ec101c5/code.php) | [Settings](src/425b1107-933d-4436-87ac-63540ec101c5/settings.json) | SPK: `Super---425b1107_933d_4436_87ac_63540ec101c5---Power`
@ -509,6 +543,11 @@ This repository contains an index (see below) of all the approved powers within
- **final class CanDelete** | [Details](src/2a69a8ab-cea0-4c75-92d5-9495cb740e0f) | [Code](src/2a69a8ab-cea0-4c75-92d5-9495cb740e0f/code.php) | [Settings](src/2a69a8ab-cea0-4c75-92d5-9495cb740e0f/settings.json) | SPK: `Super---2a69a8ab_cea0_4c75_92d5_9495cb740e0f---Power`
- **final class CanEditState** | [Details](src/cb2a82a5-aa49-4d46-b765-9b3feb118208) | [Code](src/cb2a82a5-aa49-4d46-b765-9b3feb118208/code.php) | [Settings](src/cb2a82a5-aa49-4d46-b765-9b3feb118208/settings.json) | SPK: `Super---cb2a82a5_aa49_4d46_b765_9b3feb118208---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin](#vdm-joomla-componentbuilder-compiler-architecture-joomlafour-plugin)
- **final class Extension** | [Details](src/ec808f55-6703-46c0-8a6d-33c9d4e0e9fa) | [Code](src/ec808f55-6703-46c0-8a6d-33c9d4e0e9fa/code.php) | [Settings](src/ec808f55-6703-46c0-8a6d-33c9d4e0e9fa/settings.json) | SPK: `Super---ec808f55_6703_46c0_8a6d_33c9d4e0e9fa---Power`
- **final class MainXML** | [Details](src/af6d0e6a-61d2-4250-9e2f-bed5591e2786) | [Code](src/af6d0e6a-61d2-4250-9e2f-bed5591e2786/code.php) | [Settings](src/af6d0e6a-61d2-4250-9e2f-bed5591e2786/settings.json) | SPK: `Super---af6d0e6a_61d2_4250_9e2f_bed5591e2786---Power`
- **final class Provider** | [Details](src/60c3ccc5-36dc-4480-b5c4-252c37212f61) | [Code](src/60c3ccc5-36dc-4480-b5c4-252c37212f61/code.php) | [Settings](src/60c3ccc5-36dc-4480-b5c4-252c37212f61/settings.json) | SPK: `Super---60c3ccc5_36dc_4480_b5c4_252c37212f61---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Controller](#vdm-joomla-componentbuilder-compiler-architecture-joomlathree-controller)
- **final class AllowAdd** | [Details](src/f21388dc-5ddc-4970-a3c2-55f075024762) | [Code](src/f21388dc-5ddc-4970-a3c2-55f075024762/code.php) | [Settings](src/f21388dc-5ddc-4970-a3c2-55f075024762/settings.json) | SPK: `Super---f21388dc_5ddc_4970_a3c2_55f075024762---Power`
@ -518,6 +557,11 @@ This repository contains an index (see below) of all the approved powers within
- **final class CanDelete** | [Details](src/23766738-d0a4-4d0a-8555-7e4c97c0cddd) | [Code](src/23766738-d0a4-4d0a-8555-7e4c97c0cddd/code.php) | [Settings](src/23766738-d0a4-4d0a-8555-7e4c97c0cddd/settings.json) | SPK: `Super---23766738_d0a4_4d0a_8555_7e4c97c0cddd---Power`
- **final class CanEditState** | [Details](src/bce9ac2b-9f46-413f-b046-9e8af3f7dfbe) | [Code](src/bce9ac2b-9f46-413f-b046-9e8af3f7dfbe/code.php) | [Settings](src/bce9ac2b-9f46-413f-b046-9e8af3f7dfbe/settings.json) | SPK: `Super---bce9ac2b_9f46_413f_b046_9e8af3f7dfbe---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin](#vdm-joomla-componentbuilder-compiler-architecture-joomlathree-plugin)
- **final class Extension** | [Details](src/a5f658ff-3962-475d-8cf8-c91da562bf49) | [Code](src/a5f658ff-3962-475d-8cf8-c91da562bf49/code.php) | [Settings](src/a5f658ff-3962-475d-8cf8-c91da562bf49/settings.json) | SPK: `Super---a5f658ff_3962_475d_8cf8_c91da562bf49---Power`
- **final class MainXML** | [Details](src/54e05f58-6538-42ec-ba46-b136f33e7cc7) | [Code](src/54e05f58-6538-42ec-ba46-b136f33e7cc7/code.php) | [Settings](src/54e05f58-6538-42ec-ba46-b136f33e7cc7/settings.json) | SPK: `Super---54e05f58_6538_42ec_ba46_b136f33e7cc7---Power`
- **final class Provider** | [Details](src/6dd2d394-8dde-4eb7-8505-cd7d345c49e3) | [Code](src/6dd2d394-8dde-4eb7-8505-cd7d345c49e3/code.php) | [Settings](src/6dd2d394-8dde-4eb7-8505-cd7d345c49e3/settings.json) | SPK: `Super---6dd2d394_8dde_4eb7_8505_cd7d345c49e3---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Controller](#vdm-joomla-componentbuilder-compiler-interfaces-architecture-controller)
- **interface AllowAddInterface** | [Details](src/c9700450-4f44-4455-bc86-6a7660daadee) | [Code](src/c9700450-4f44-4455-bc86-6a7660daadee/code.php) | [Settings](src/c9700450-4f44-4455-bc86-6a7660daadee/settings.json) | SPK: `Super---c9700450_4f44_4455_bc86_6a7660daadee---Power`
@ -527,6 +571,10 @@ This repository contains an index (see below) of all the approved powers within
- **interface CanDeleteInterface** | [Details](src/e00a7d1d-6d80-41c5-bf13-32d41bc5bf91) | [Code](src/e00a7d1d-6d80-41c5-bf13-32d41bc5bf91/code.php) | [Settings](src/e00a7d1d-6d80-41c5-bf13-32d41bc5bf91/settings.json) | SPK: `Super---e00a7d1d_6d80_41c5_bf13_32d41bc5bf91---Power`
- **interface CanEditStateInterface** | [Details](src/600515b1-493f-4448-96fe-018e54e087c8) | [Code](src/600515b1-493f-4448-96fe-018e54e087c8/code.php) | [Settings](src/600515b1-493f-4448-96fe-018e54e087c8/settings.json) | SPK: `Super---600515b1_493f_4448_96fe_018e54e087c8---Power`
- **Namespace**: [VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin](#vdm-joomla-componentbuilder-compiler-interfaces-architecture-plugin)
- **interface ExtensionInterface** | [Details](src/914db7f5-82d8-4d3b-a1c1-eb476b1898c2) | [Code](src/914db7f5-82d8-4d3b-a1c1-eb476b1898c2/code.php) | [Settings](src/914db7f5-82d8-4d3b-a1c1-eb476b1898c2/settings.json) | SPK: `Super---914db7f5_82d8_4d3b_a1c1_eb476b1898c2---Power`
- **interface ProviderInterface** | [Details](src/d6ae90a5-44b4-4ce4-aedc-86c90a242912) | [Code](src/d6ae90a5-44b4-4ce4-aedc-86c90a242912/code.php) | [Settings](src/d6ae90a5-44b4-4ce4-aedc-86c90a242912/settings.json) | SPK: `Super---d6ae90a5_44b4_4ce4_aedc_86c90a242912---Power`
> remember to replace the `---` with `___` in the SPK to activate that Power in your code
---

View File

@ -17,7 +17,11 @@ class Power #Gold {
+ getTable(Container $container) : Table
+ getGrep(Container $container) : Grep
+ getRemoteGet(Container $container) : Get
+ getRemoteSet(Container $container) : Set
+ getItemReadme(Container $container) : ItemReadme
+ getMainReadme(Container $container) : MainReadme
+ getParser(Container $container) : Parser
+ getPlantuml(Container $container) : Plantuml
}
note right of Power::register
@ -27,7 +31,7 @@ note right of Power::register
return: void
end note
note right of Power::getConfig
note left of Power::getConfig
Get The Config Class.
since: 3.2.0
@ -41,7 +45,7 @@ note right of Power::getTable
return: Table
end note
note right of Power::getGrep
note left of Power::getGrep
Get The Grep Class.
since: 3.2.0
@ -55,12 +59,40 @@ note right of Power::getRemoteGet
return: Get
end note
note left of Power::getRemoteSet
Get The Remote Set Class.
since: 5.0.3
return: Set
end note
note right of Power::getItemReadme
Get The Readme Class.
since: 5.0.3
return: ItemReadme
end note
note left of Power::getMainReadme
Get The Readme Class.
since: 5.0.3
return: MainReadme
end note
note right of Power::getParser
Get The Parser Class.
since: 3.2.0
return: Parser
end note
note left of Power::getPlantuml
Get The Plantuml Class.
since: 5.0.3
return: Plantuml
end note
@enduml
```

View File

@ -18,7 +18,11 @@ use VDM\Joomla\Componentbuilder\Power\Config;
use VDM\Joomla\Componentbuilder\Table;
use VDM\Joomla\Componentbuilder\Power\Grep;
use VDM\Joomla\Componentbuilder\Power\Remote\Get;
use VDM\Joomla\Componentbuilder\Power\Remote\Set;
use VDM\Joomla\Componentbuilder\Power\Parser;
use VDM\Joomla\Componentbuilder\Power\Plantuml;
use VDM\Joomla\Componentbuilder\Power\Readme\Item as ItemReadme;
use VDM\Joomla\Componentbuilder\Power\Readme\Main as MainReadme;
/**
@ -50,8 +54,20 @@ class Power implements ServiceProviderInterface
$container->alias(Get::class, 'Power.Remote.Get')
->share('Power.Remote.Get', [$this, 'getRemoteGet'], true);
$container->alias(Set::class, 'Power.Remote.Set')
->share('Power.Remote.Set', [$this, 'getRemoteSet'], true);
$container->alias(Parser::class, 'Power.Parser')
->share('Power.Parser', [$this, 'getParser'], true);
$container->alias(Plantuml::class, 'Power.Plantuml')
->share('Power.Plantuml', [$this, 'getPlantuml'], true);
$container->alias(ItemReadme::class, 'Power.Readme.Item')
->share('Power.Readme.Item', [$this, 'getItemReadme'], true);
$container->alias(MainReadme::class, 'Power.Readme.Main')
->share('Power.Readme.Main', [$this, 'getMainReadme'], true);
}
/**
@ -113,6 +129,55 @@ class Power implements ServiceProviderInterface
);
}
/**
* Get The Remote Set Class.
*
* @param Container $container The DI container.
*
* @return Set
* @since 5.0.3
*/
public function getRemoteSet(Container $container): Set
{
return new Set(
$container->get('Config')->approved_paths,
$container->get('Power.Grep'),
$container->get('Data.Items'),
$container->get('Power.Readme.Item'),
$container->get('Power.Readme.Main'),
$container->get('Gitea.Repository.Contents'), null, null, null,
$container->get('Power.Parser')
);
}
/**
* Get The Readme Class.
*
* @param Container $container The DI container.
*
* @return ItemReadme
* @since 5.0.3
*/
public function getItemReadme(Container $container): ItemReadme
{
return new ItemReadme(
$container->get('Power.Plantuml')
);
}
/**
* Get The Readme Class.
*
* @param Container $container The DI container.
*
* @return MainReadme
* @since 5.0.3
*/
public function getMainReadme(Container $container): MainReadme
{
return new MainReadme();
}
/**
* Get The Parser Class.
*
@ -124,6 +189,19 @@ class Power implements ServiceProviderInterface
public function getParser(Container $container): Parser
{
return new Parser();
}
/**
* Get The Plantuml Class.
*
* @param Container $container The DI container.
*
* @return Plantuml
* @since 5.0.3
*/
public function getPlantuml(Container $container): Plantuml
{
return new Plantuml();
}
}

View File

@ -20,8 +20,20 @@
$container->alias(Get::class, 'Power.Remote.Get')
->share('Power.Remote.Get', [$this, 'getRemoteGet'], true);
$container->alias(Set::class, 'Power.Remote.Set')
->share('Power.Remote.Set', [$this, 'getRemoteSet'], true);
$container->alias(Parser::class, 'Power.Parser')
->share('Power.Parser', [$this, 'getParser'], true);
$container->alias(Plantuml::class, 'Power.Plantuml')
->share('Power.Plantuml', [$this, 'getPlantuml'], true);
$container->alias(ItemReadme::class, 'Power.Readme.Item')
->share('Power.Readme.Item', [$this, 'getItemReadme'], true);
$container->alias(MainReadme::class, 'Power.Readme.Main')
->share('Power.Readme.Main', [$this, 'getMainReadme'], true);
}
/**
@ -83,6 +95,55 @@
);
}
/**
* Get The Remote Set Class.
*
* @param Container $container The DI container.
*
* @return Set
* @since 5.0.3
*/
public function getRemoteSet(Container $container): Set
{
return new Set(
$container->get('Config')->approved_paths,
$container->get('Power.Grep'),
$container->get('Data.Items'),
$container->get('Power.Readme.Item'),
$container->get('Power.Readme.Main'),
$container->get('Gitea.Repository.Contents'), null, null, null,
$container->get('Power.Parser')
);
}
/**
* Get The Readme Class.
*
* @param Container $container The DI container.
*
* @return ItemReadme
* @since 5.0.3
*/
public function getItemReadme(Container $container): ItemReadme
{
return new ItemReadme(
$container->get('Power.Plantuml')
);
}
/**
* Get The Readme Class.
*
* @param Container $container The DI container.
*
* @return MainReadme
* @since 5.0.3
*/
public function getMainReadme(Container $container): MainReadme
{
return new MainReadme();
}
/**
* Get The Parser Class.
*
@ -94,4 +155,17 @@
public function getParser(Container $container): Parser
{
return new Parser();
}
/**
* Get The Plantuml Class.
*
* @param Container $container The DI container.
*
* @return Plantuml
* @since 5.0.3
*/
public function getPlantuml(Container $container): Plantuml
{
return new Plantuml();
}

View File

@ -29,8 +29,24 @@
"as": "default"
},
"use_selection4": {
"use": "caf559ee-8337-4f07-9e4a-394d4e06afdc",
"as": "default"
},
"use_selection5": {
"use": "95d0e03f-24fd-4412-bc2e-f0899fcc3205",
"as": "default"
},
"use_selection6": {
"use": "ff5e9e63-86d0-4691-ab59-d4b9d9154096",
"as": "default"
},
"use_selection7": {
"use": "efb1d0f8-2d14-4d2c-8b5f-4fcdd9df45a5",
"as": "ItemReadme"
},
"use_selection8": {
"use": "0d08c583-04d5-454e-b756-48ca05e1651a",
"as": "MainReadme"
}
},
"extendsinterfaces": null,

View File

@ -0,0 +1,156 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Infusion (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree**
```uml
@startuml
class Infusion << (F,LightGreen) >> #RoyalBlue {
# Config $config
# Placeholder $placeholder
# Header $header
# Event $event
# Data $data
# InstallScript $installscript
# Extension $extension
# MainXML $mainxml
# ContentMulti $contentmulti
# FieldsetExtension $fieldsetextension
+ __construct(Config $config, Placeholder $placeholder, ...)
+ set() : void
# triggerBeforeInfusionEvent(object $plugin) : void
# setPlaceholders(object $plugin) : void
# buildPluginContent(object $plugin) : void
# setExtensionClassHeader(object $plugin) : void
# setExtensionClass(object $plugin) : void
# setInstallClass(object $plugin) : void
# setFieldsets(object $plugin) : void
# setMainXml(object $plugin) : void
# triggerAfterInfusionEvent(object $plugin) : void
}
note right of Infusion::__construct
Constructor.
since: 5.0.2
arguments:
Config $config
Placeholder $placeholder
Header $header
Event $event
Data $data
InstallScript $installscript
Extension $extension
MainXML $mainxml
ContentMulti $contentmulti
FieldsetExtension $fieldsetextension
end note
note left of Infusion::set
Infuse the plugin data into the content.
This method processes each plugin in the data set, triggering events
before and after infusion, setting placeholders, and adding content
such as headers, classes, and XML configurations.
since: 5.0.2
return: void
end note
note right of Infusion::triggerBeforeInfusionEvent
Trigger the event before infusing the plugin data.
since: 5.0.2
return: void
end note
note left of Infusion::setPlaceholders
Set placeholders based on plugin data.
since: 5.0.2
return: void
end note
note right of Infusion::buildPluginContent
Build and set the content related to the plugin.
since: 5.0.2
return: void
end note
note left of Infusion::setExtensionClassHeader
Set the extension class header content.
since: 5.0.2
return: void
end note
note right of Infusion::setExtensionClass
Set the extension class content.
since: 5.0.2
return: void
end note
note left of Infusion::setInstallClass
Set the install script content, if needed.
since: 5.0.2
return: void
end note
note right of Infusion::setFieldsets
Set fieldset content based on form files.
since: 5.0.2
return: void
end note
note left of Infusion::setMainXml
Set the main XML content for the plugin.
since: 5.0.2
return: void
end note
note right of Infusion::triggerAfterInfusionEvent
Trigger the event after infusing the plugin data.
since: 5.0.2
return: void
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---03b75302_98ba_47ac_859f_1f49b738f66c---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,338 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HeaderInterface as Header;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Data;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\GetScriptInterface as InstallScript;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface as Extension;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface as MainXML;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\InfusionInterface;
/**
* Joomla 3 Plugin Infusion Class
*
* @since 5.0.2
*/
final class Infusion implements InfusionInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Header Class.
*
* @var Header
* @since 5.0.2
*/
protected Header $header;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The Plugin Data Class.
*
* @var Data
* @since 5.0.2
*/
protected Data $data;
/**
* The Get Script Class.
*
* @var InstallScript
* @since 5.0.2
*/
protected InstallScript $installscript;
/**
* The Extension Class.
*
* @var Extension
* @since 5.0.2
*/
protected Extension $extension;
/**
* The Main XML Class.
*
* @var MainXML
* @since 5.0.2
*/
protected MainXML $mainxml;
/**
* The Content Multi Class.
*
* @var ContentMulti
* @since 5.0.2
*/
protected ContentMulti $contentmulti;
/**
* The Fieldset Extension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Header $header The HeaderInterface Class.
* @param Event $event The EventInterface Class.
* @param Data $data The PluginDataInterface Class.
* @param InstallScript $installscript The GetScriptInterface Class.
* @param Extension $extension The ExtensionInterface Class.
* @param MainXML $mainxml The MainXMLInterface Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Placeholder $placeholder, Header $header,
Event $event, Data $data, InstallScript $installscript,
Extension $extension, MainXML $mainxml,
ContentMulti $contentmulti,
FieldsetExtension $fieldsetextension)
{
$this->config = $config;
$this->placeholder = $placeholder;
$this->header = $header;
$this->event = $event;
$this->data = $data;
$this->installscript = $installscript;
$this->extension = $extension;
$this->mainxml = $mainxml;
$this->contentmulti = $contentmulti;
$this->fieldsetextension = $fieldsetextension;
}
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void
{
if (!$this->data->exists())
{
return;
}
foreach ($this->data->get() as $plugin)
{
if (!ObjectHelper::check($plugin))
{
continue;
}
$this->triggerBeforeInfusionEvent($plugin);
$this->setPlaceholders($plugin);
$this->buildPluginContent($plugin);
$this->triggerAfterInfusionEvent($plugin);
}
}
/**
* Trigger the event before infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerBeforeInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onBeforeInfusePluginData', [&$plugin]);
}
/**
* Set placeholders based on plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setPlaceholders($plugin): void
{
$this->placeholder->set('PluginGroupNamespace', $plugin->group_namespace ?? '');
$this->placeholder->set('PluginNamespace', $plugin->namespace ?? '');
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
$this->config->set('lang_prefix', $plugin->lang_prefix);
}
/**
* Build and set the content related to the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function buildPluginContent($plugin): void
{
$this->setExtensionClassHeader($plugin);
$this->setExtensionClass($plugin);
if ($plugin->add_install_script)
{
$this->setInstallClass($plugin);
}
if (isset($plugin->form_files) && ArrayHelper::check($plugin->form_files))
{
$this->setFieldsets($plugin);
}
$this->setMainXml($plugin);
}
/**
* Set the extension class header content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClassHeader($plugin): void
{
$headerContent = trim(
$this->header->get('plugin.extension.header', $plugin->class_name)
. PHP_EOL . ($plugin->header ?? '')
);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS_HEADER", $headerContent);
}
/**
* Set the extension class content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClass($plugin): void
{
$extensionContent = $this->extension->get($plugin);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS", $extensionContent);
}
/**
* Set the install script content, if needed.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setInstallClass($plugin): void
{
$installContent = $this->installscript->get($plugin);
$this->contentmulti->set("{$plugin->key}|INSTALL_CLASS", $installContent);
}
/**
* Set fieldset content based on form files.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setFieldsets($plugin): void
{
foreach ($plugin->form_files as $file => $files)
{
foreach ($files as $field_name => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$fieldsetContent = $this->fieldsetextension->get($plugin, $fields);
$this->contentmulti->set(
"{$plugin->key}|FIELDSET_{$file}{$field_name}{$fieldset}",
$fieldsetContent
);
}
}
}
}
/**
* Set the main XML content for the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setMainXml($plugin): void
{
$mainXmlContent = $this->mainxml->get($plugin);
$this->contentmulti->set("{$plugin->key}|MAINXML", $mainXmlContent);
}
/**
* Trigger the event after infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerAfterInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onAfterInfusePluginData', [&$plugin]);
}
}

View File

@ -0,0 +1,300 @@
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Header Class.
*
* @var Header
* @since 5.0.2
*/
protected Header $header;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The Plugin Data Class.
*
* @var Data
* @since 5.0.2
*/
protected Data $data;
/**
* The Get Script Class.
*
* @var InstallScript
* @since 5.0.2
*/
protected InstallScript $installscript;
/**
* The Extension Class.
*
* @var Extension
* @since 5.0.2
*/
protected Extension $extension;
/**
* The Main XML Class.
*
* @var MainXML
* @since 5.0.2
*/
protected MainXML $mainxml;
/**
* The Content Multi Class.
*
* @var ContentMulti
* @since 5.0.2
*/
protected ContentMulti $contentmulti;
/**
* The Fieldset Extension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Header $header The HeaderInterface Class.
* @param Event $event The EventInterface Class.
* @param Data $data The PluginDataInterface Class.
* @param InstallScript $installscript The GetScriptInterface Class.
* @param Extension $extension The ExtensionInterface Class.
* @param MainXML $mainxml The MainXMLInterface Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Placeholder $placeholder, Header $header,
Event $event, Data $data, InstallScript $installscript,
Extension $extension, MainXML $mainxml,
ContentMulti $contentmulti,
FieldsetExtension $fieldsetextension)
{
$this->config = $config;
$this->placeholder = $placeholder;
$this->header = $header;
$this->event = $event;
$this->data = $data;
$this->installscript = $installscript;
$this->extension = $extension;
$this->mainxml = $mainxml;
$this->contentmulti = $contentmulti;
$this->fieldsetextension = $fieldsetextension;
}
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void
{
if (!$this->data->exists())
{
return;
}
foreach ($this->data->get() as $plugin)
{
if (!ObjectHelper::check($plugin))
{
continue;
}
$this->triggerBeforeInfusionEvent($plugin);
$this->setPlaceholders($plugin);
$this->buildPluginContent($plugin);
$this->triggerAfterInfusionEvent($plugin);
}
}
/**
* Trigger the event before infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerBeforeInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onBeforeInfusePluginData', [&$plugin]);
}
/**
* Set placeholders based on plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setPlaceholders($plugin): void
{
$this->placeholder->set('PluginGroupNamespace', $plugin->group_namespace ?? '');
$this->placeholder->set('PluginNamespace', $plugin->namespace ?? '');
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
$this->config->set('lang_prefix', $plugin->lang_prefix);
}
/**
* Build and set the content related to the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function buildPluginContent($plugin): void
{
$this->setExtensionClassHeader($plugin);
$this->setExtensionClass($plugin);
if ($plugin->add_install_script)
{
$this->setInstallClass($plugin);
}
if (isset($plugin->form_files) && ArrayHelper::check($plugin->form_files))
{
$this->setFieldsets($plugin);
}
$this->setMainXml($plugin);
}
/**
* Set the extension class header content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClassHeader($plugin): void
{
$headerContent = trim(
$this->header->get('plugin.extension.header', $plugin->class_name)
. PHP_EOL . ($plugin->header ?? '')
);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS_HEADER", $headerContent);
}
/**
* Set the extension class content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClass($plugin): void
{
$extensionContent = $this->extension->get($plugin);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS", $extensionContent);
}
/**
* Set the install script content, if needed.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setInstallClass($plugin): void
{
$installContent = $this->installscript->get($plugin);
$this->contentmulti->set("{$plugin->key}|INSTALL_CLASS", $installContent);
}
/**
* Set fieldset content based on form files.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setFieldsets($plugin): void
{
foreach ($plugin->form_files as $file => $files)
{
foreach ($files as $field_name => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$fieldsetContent = $this->fieldsetextension->get($plugin, $fields);
$this->contentmulti->set(
"{$plugin->key}|FIELDSET_{$file}{$field_name}{$fieldset}",
$fieldsetContent
);
}
}
}
}
/**
* Set the main XML content for the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setMainXml($plugin): void
{
$mainXmlContent = $this->mainxml->get($plugin);
$this->contentmulti->set("{$plugin->key}|MAINXML", $mainXmlContent);
}
/**
* Trigger the event after infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerAfterInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onAfterInfusePluginData', [&$plugin]);
}

View File

@ -0,0 +1,70 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "03b75302-98ba-47ac-859f-1f49b738f66c",
"implements": [
"40e17114-2193-4a61-9233-47b5f4193665"
],
"load_selection": null,
"name": "Infusion",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Joomlaplugin.J3.Infusion",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",
"as": "default"
},
"use_selection1": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection2": {
"use": "3a777d70-52ad-49ec-9016-6f7438608613",
"as": "Header"
},
"use_selection3": {
"use": "20ed72b0-fcac-4344-aee1-8a65e3bf221d",
"as": "Event"
},
"use_selection4": {
"use": "8cc85656-a925-4a46-a49b-83c72167fd6a",
"as": "Data"
},
"use_selection5": {
"use": "2e6731ba-3a03-4836-b2c2-4e50e38cb890",
"as": "InstallScript"
},
"use_selection6": {
"use": "914db7f5-82d8-4d3b-a1c1-eb476b1898c2",
"as": "Extension"
},
"use_selection7": {
"use": "97177ca9-a51a-4d24-81e1-8747b6e7d76c",
"as": "MainXML"
},
"use_selection8": {
"use": "5f57ff1a-c196-45b1-a2ac-33766b44fb95",
"as": "default"
},
"use_selection9": {
"use": "23f459a4-7c2a-4cbf-b0a6-8a11954140a9",
"as": "default"
},
"use_selection10": {
"use": "91004529-94a9-4590-b842-e7c6b624ecf5",
"as": "default"
},
"use_selection11": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Joomlaplugin.JoomlaThree.Infusion",
"description": "Joomla 3 Plugin Infusion Class\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -6,12 +6,12 @@
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# class Infusion (Details)
# final class Infusion (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Power**
```uml
@startuml
class Infusion #Gold {
class Infusion << (F,LightGreen) >> #RoyalBlue {
# Config $config
# Power $power
# Content $content

View File

@ -30,7 +30,7 @@ use VDM\Joomla\Utilities\ObjectHelper;
* Compiler Power Infusion
* @since 3.2.0
*/
class Infusion
final class Infusion
{
/**
* The Config Class.

View File

@ -8,7 +8,7 @@
"name": "Infusion",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Power.Infusion",
"type": "class",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",

View File

@ -0,0 +1,129 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Set (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Language**
```uml
@startuml
class Set << (F,LightGreen) >> #RoyalBlue {
# Config $config
# Language $language
# Multilingual $multilingual
# Languages $languages
# Insert $insert
# Update $update
+ __construct(Config $config, Language $language, ...)
+ execute(array $strings, int $target_id, ...) : void
# processString(string $string, array $strings, ...) : void
# updateOrInsertString(string $string, $multiLangString, ...) : void
# getTargets(array $multiLangString, string $target, ...) : array
}
note right of Set::__construct
Constructor.
since: 5.0.2
arguments:
Config $config
Language $language
Multilingual $multilingual
Languages $languages
Insert $insert
Update $update
end note
note right of Set::execute
Set the current language values to the database.
This method inserts or updates language strings in the database based on the current state.
since: 5.0.2
return: void
arguments:
array $strings
int $target_id
string $target = 'components'
end note
note right of Set::processString
Process an individual language string for database update or insert.
since: 5.0.2
return: void
arguments:
string $string
array $strings
string $area
string $placeholder
$multiLangString
string $target
int $target_id
string $today
$counterInsert
$counterUpdate
end note
note right of Set::updateOrInsertString
Update or insert a language string in the database.
since: 5.0.2
return: void
arguments:
string $string
$multiLangString
string $target
int $target_id
string $today
$counterInsert
$counterUpdate
end note
note right of Set::getTargets
Get targets for a given string.
since: 5.0.2
return: array
arguments:
array $multiLangString
string $target
int $target_id
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---058cfcd7_1f84_4cc6_8bcc_7672f316881d---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,277 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Multilingual;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Languages;
use VDM\Joomla\Componentbuilder\Compiler\Language\Insert;
use VDM\Joomla\Componentbuilder\Compiler\Language\Update;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\MathHelper;
/**
* Compiler Set Language Strings
*
* @since 5.0.2
*/
final class Set
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Insert Class.
*
* @var Insert
* @since 5.0.2
*/
protected Insert $insert;
/**
* The Update Class.
*
* @var Update
* @since 5.0.2
*/
protected Update $update;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Messages $messages The Language Messages Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Languages $languages The Languages Class.
* @param Insert $insert The Insert Class.
* @param Update $update The Update Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language,
Multilingual $multilingual, Languages $languages,
Insert $insert, Update $update)
{
$this->config = $config;
$this->language = $language;
$this->multilingual = $multilingual;
$this->languages = $languages;
$this->insert = $insert;
$this->update = $update;
}
/**
* Set the current language values to the database.
*
* This method inserts or updates language strings in the database based on the current state.
*
* @param array $strings The language strings to process.
* @param int $target_id The target component ID.
* @param string $target The target extension type (default is 'components').
*
* @return void
* @since 5.0.2
*/
public function execute(array $strings, int $target_id, string $target = 'components'): void
{
$counterInsert = 0;
$counterUpdate = 0;
$today = Factory::getDate()->toSql();
$langTag = $this->config->get('lang_tag', 'en-GB');
$multiLangString = $this->multilingual->get($target, []);
foreach ($this->languages->get("{$target}.{$langTag}") as $area => $placeholders)
{
foreach ($placeholders as $placeholder => $string)
{
if (StringHelper::check($string))
{
$this->processString(
$string, $strings, $area, $placeholder, $multiLangString, $target, $target_id, $today, $counterInsert, $counterUpdate
);
}
}
}
$this->multilingual->set($target, $multiLangString);
$this->update->execute();
$this->insert->execute($target);
}
/**
* Process an individual language string for database update or insert.
*
* @param string $string The language string to process.
* @param array $strings The language strings array.
* @param string $area The targeted area.
* @param string $placeholder The placeholder.
* @param array &$multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
* @param string $today The current date.
* @param int &$counterInsert The insert counter.
* @param int &$counterUpdate The update counter.
*
* @return void
* @since 5.0.2
*/
protected function processString(string $string, array &$strings, string $area,
string $placeholder, array &$multiLangString, string $target,
int $target_id, string $today, int &$counterInsert, int &$counterUpdate): void
{
$remove = false;
if (isset($multiLangString[$string]))
{
if (isset($multiLangString[$string]['translation']) && JsonHelper::check($multiLangString[$string]['translation']))
{
$multiLangString[$string]['translation'] = json_decode((string) $multiLangString[$string]['translation'], true);
}
if (isset($multiLangString[$string]['translation']) && ArrayHelper::check($multiLangString[$string]['translation']))
{
foreach ($multiLangString[$string]['translation'] as $translations)
{
if (isset($translations['language']) && isset($translations['translation']))
{
$multiLangTag = $translations['language'];
$this->languages->set("{$target}.{$multiLangTag}.{$area}.{$placeholder}", $this->language->fix($translations['translation']));
}
}
}
else
{
$remove = true;
}
}
if (StringHelper::check($string) && ($key = array_search($string, $strings)) !== false)
{
$this->updateOrInsertString($string, $multiLangString, $target, $target_id, $today, $counterInsert, $counterUpdate);
if ($remove)
{
unset($multiLangString[$string]);
}
unset($strings[$key]);
}
}
/**
* Update or insert a language string in the database.
*
* @param string $string The language string to update or insert.
* @param array &$multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
* @param string $today The current date.
* @param int &$counterInsert The insert counter.
* @param int &$counterUpdate The update counter.
*
* @return void
* @since 5.0.2
*/
protected function updateOrInsertString(string $string, array &$multiLangString, string $target, int $target_id, string $today, int &$counterInsert, int &$counterUpdate): void
{
if (isset($multiLangString[$string]))
{
$id = $multiLangString[$string]['id'];
$targets = $this->getTargets($multiLangString[$string], $target, $target_id);
$this->update->set($id, $target, $targets, 1, $today, $counterUpdate);
$counterUpdate++;
$this->update->execute(50);
}
else
{
$this->insert->set($target, $counterInsert, json_encode([$target_id]));
$this->insert->set($target, $counterInsert, $string);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, $today);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, 1);
$counterInsert++;
$this->insert->execute($target, 100);
}
}
/**
* Get targets for a given string.
*
* @param array $multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
*
* @return array The updated targets array.
* @since 5.0.2
*/
protected function getTargets(array $multiLangString, string $target, int $target_id): array
{
if (JsonHelper::check($multiLangString[$target]))
{
$targets = (array) json_decode((string) $multiLangString[$target], true);
if (!in_array($target_id, $targets))
{
$targets[] = $target_id;
}
}
else
{
$targets = [$target_id];
}
return $targets;
}
}

View File

@ -0,0 +1,241 @@
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Insert Class.
*
* @var Insert
* @since 5.0.2
*/
protected Insert $insert;
/**
* The Update Class.
*
* @var Update
* @since 5.0.2
*/
protected Update $update;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Messages $messages The Language Messages Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Languages $languages The Languages Class.
* @param Insert $insert The Insert Class.
* @param Update $update The Update Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language,
Multilingual $multilingual, Languages $languages,
Insert $insert, Update $update)
{
$this->config = $config;
$this->language = $language;
$this->multilingual = $multilingual;
$this->languages = $languages;
$this->insert = $insert;
$this->update = $update;
}
/**
* Set the current language values to the database.
*
* This method inserts or updates language strings in the database based on the current state.
*
* @param array $strings The language strings to process.
* @param int $target_id The target component ID.
* @param string $target The target extension type (default is 'components').
*
* @return void
* @since 5.0.2
*/
public function execute(array $strings, int $target_id, string $target = 'components'): void
{
$counterInsert = 0;
$counterUpdate = 0;
$today = Factory::getDate()->toSql();
$langTag = $this->config->get('lang_tag', 'en-GB');
$multiLangString = $this->multilingual->get($target, []);
foreach ($this->languages->get("{$target}.{$langTag}") as $area => $placeholders)
{
foreach ($placeholders as $placeholder => $string)
{
if (StringHelper::check($string))
{
$this->processString(
$string, $strings, $area, $placeholder, $multiLangString, $target, $target_id, $today, $counterInsert, $counterUpdate
);
}
}
}
$this->multilingual->set($target, $multiLangString);
$this->update->execute();
$this->insert->execute($target);
}
/**
* Process an individual language string for database update or insert.
*
* @param string $string The language string to process.
* @param array $strings The language strings array.
* @param string $area The targeted area.
* @param string $placeholder The placeholder.
* @param array &$multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
* @param string $today The current date.
* @param int &$counterInsert The insert counter.
* @param int &$counterUpdate The update counter.
*
* @return void
* @since 5.0.2
*/
protected function processString(string $string, array &$strings, string $area,
string $placeholder, array &$multiLangString, string $target,
int $target_id, string $today, int &$counterInsert, int &$counterUpdate): void
{
$remove = false;
if (isset($multiLangString[$string]))
{
if (isset($multiLangString[$string]['translation']) && JsonHelper::check($multiLangString[$string]['translation']))
{
$multiLangString[$string]['translation'] = json_decode((string) $multiLangString[$string]['translation'], true);
}
if (isset($multiLangString[$string]['translation']) && ArrayHelper::check($multiLangString[$string]['translation']))
{
foreach ($multiLangString[$string]['translation'] as $translations)
{
if (isset($translations['language']) && isset($translations['translation']))
{
$multiLangTag = $translations['language'];
$this->languages->set("{$target}.{$multiLangTag}.{$area}.{$placeholder}", $this->language->fix($translations['translation']));
}
}
}
else
{
$remove = true;
}
}
if (StringHelper::check($string) && ($key = array_search($string, $strings)) !== false)
{
$this->updateOrInsertString($string, $multiLangString, $target, $target_id, $today, $counterInsert, $counterUpdate);
if ($remove)
{
unset($multiLangString[$string]);
}
unset($strings[$key]);
}
}
/**
* Update or insert a language string in the database.
*
* @param string $string The language string to update or insert.
* @param array &$multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
* @param string $today The current date.
* @param int &$counterInsert The insert counter.
* @param int &$counterUpdate The update counter.
*
* @return void
* @since 5.0.2
*/
protected function updateOrInsertString(string $string, array &$multiLangString, string $target, int $target_id, string $today, int &$counterInsert, int &$counterUpdate): void
{
if (isset($multiLangString[$string]))
{
$id = $multiLangString[$string]['id'];
$targets = $this->getTargets($multiLangString[$string], $target, $target_id);
$this->update->set($id, $target, $targets, 1, $today, $counterUpdate);
$counterUpdate++;
$this->update->execute(50);
}
else
{
$this->insert->set($target, $counterInsert, json_encode([$target_id]));
$this->insert->set($target, $counterInsert, $string);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, $today);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, 1);
$counterInsert++;
$this->insert->execute($target, 100);
}
}
/**
* Get targets for a given string.
*
* @param array $multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
*
* @return array The updated targets array.
* @since 5.0.2
*/
protected function getTargets(array $multiLangString, string $target, int $target_id): array
{
if (JsonHelper::check($multiLangString[$target]))
{
$targets = (array) json_decode((string) $multiLangString[$target], true);
if (!in_array($target_id, $targets))
{
$targets[] = $target_id;
}
}
else
{
$targets = [$target_id];
}
return $targets;
}

View File

@ -0,0 +1,60 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "058cfcd7-1f84-4cc6-8bcc-7672f316881d",
"implements": null,
"load_selection": null,
"name": "Set",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Language.Set",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",
"as": "default"
},
"use_selection1": {
"use": "8eee7df5-2775-41a9-9372-c46c5939a252",
"as": "default"
},
"use_selection3": {
"use": "a8c6158a-6fd2-476b-a5ea-c81f1ecd2356",
"as": "default"
},
"use_selection4": {
"use": "7526a39a-ada3-4499-8d75-81beff33f949",
"as": "default"
},
"use_selection5": {
"use": "1d051a2f-0691-45a8-b3d9-d0c1adcd73bc",
"as": "default"
},
"use_selection6": {
"use": "375543cd-5f2a-4893-982e-a73eaa55360d",
"as": "default"
},
"use_selection7": {
"use": "1f28cb53-60d9-4db1-b517-3c7dc6b429ef",
"as": "default"
},
"use_selection8": {
"use": "4b225c51-d293-48e4-b3f6-5136cf5c3f18",
"as": "default"
},
"use_selection9": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
},
"use_selection10": {
"use": "152c8793-8b75-4715-996a-257b9f65451c",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Language.Set",
"description": "Compiler Set Language Strings\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;",
"composer": ""
}

View File

@ -0,0 +1,96 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Purge (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Language**
```uml
@startuml
class Purge << (F,LightGreen) >> #RoyalBlue {
# Update $update
# $db
+ __construct(Update $update)
+ execute(array $values, int $targetId, ...) : void
# handleUnlinkedString(array $item, array $targetTypes, ...) : void
# removeExitingLangString(int $id) : void
}
note right of Purge::__construct
Constructor.
since: 5.0.2
end note
note right of Purge::execute
Purge the unused language strings.
This method removes or updates language strings that are no longer linked
to the specified component. It checks if the strings are linked to other
extensions and either updates, archives, or deletes them based on the
conditions.
since: 5.0.2
return: void
arguments:
array $values
int $targetId
string $target = 'components'
end note
note right of Purge::handleUnlinkedString
Handle strings that are unlinked from the current component.
This method checks if a string is linked to other extensions and either updates,
archives, or deletes it based on the conditions.
since: 5.0.2
return: void
arguments:
array $item
array $targetTypes
array $targets
string $today
int $counter
end note
note right of Purge::removeExitingLangString
Remove existing language translation strings.
This method deletes a language string from the database based on its ID.
since: 5.0.2
return: void
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---0b0e574c_aab4_4eaf_96d8_d7210d8ed93e---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,198 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
use VDM\Joomla\Componentbuilder\Compiler\Language\Update;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* Compiler Remove Existing Language Strings
*
* @since 5.0.2
*/
final class Purge
{
/**
* The Update Class.
*
* @var Update
* @since 5.0.2
*/
protected Update $update;
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @param Update $update The Update Class.
*
* @since 5.0.2
*/
public function __construct(Update $update)
{
$this->update = $update;
$this->db = Factory::getDbo();
}
/**
* Purge the unused language strings.
*
* This method removes or updates language strings that are no longer linked
* to the specified component. It checks if the strings are linked to other
* extensions and either updates, archives, or deletes them based on the
* conditions.
*
* @param array $values The active strings.
* @param int $targetId The target component ID.
* @param string $target The target extension type (default is 'components').
*
* @return void
* @since 5.0.2
*/
public function execute(array $values, int $targetId, string $target = 'components'): void
{
$target_types = ['components' => 'components', 'modules' => 'modules', 'plugins' => 'plugins'];
if (isset($target_types[$target]))
{
unset($target_types[$target]);
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from($this->db->quoteName('#__componentbuilder_language_translation', 'a'))
->select($this->db->quoteName(['a.id', 'a.translation', 'a.components', 'a.modules', 'a.plugins']))
->where($this->db->quoteName('a.source') . ' NOT IN (' . implode(',', array_map(fn($a) => $this->db->quote($a), $values)) . ')')
->where($this->db->quoteName('a.published') . ' = 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
$counterUpdate = 0;
$otherStrings = $this->db->loadAssocList();
$today = Factory::getDate()->toSql();
foreach ($otherStrings as $item)
{
if (JsonHelper::check($item[$target]))
{
$targets = (array) json_decode((string) $item[$target], true);
if (($key = array_search($targetId, $targets)) !== false)
{
unset($targets[$key]);
if (ArrayHelper::check($targets))
{
$this->update->set($item['id'], $target, $targets, 1, $today, $counterUpdate);
$counterUpdate++;
$this->update->execute(50);
}
else
{
$this->handleUnlinkedString($item, $target_types, $targets, $today, $counterUpdate);
}
}
}
}
$this->update->execute();
}
}
}
/**
* Handle strings that are unlinked from the current component.
*
* This method checks if a string is linked to other extensions and either updates,
* archives, or deletes it based on the conditions.
*
* @param array $item The language string item.
* @param array $targetTypes The target extension types.
* @param array $targets The targets to update.
* @param string $today The current date.
* @param int $counter The update counter.
*
* @return void
* @since 5.0.2
*/
protected function handleUnlinkedString(array $item, array $targetTypes, array $targets, string $today, int &$counter): void
{
// the action (1 = remove, 2 = archive, 0 = do nothing)
$action_with_string = 1;
foreach ($targetTypes as $other_target)
{
if ($action_with_string && JsonHelper::check($item[$other_target]))
{
$other_targets = (array) json_decode((string) $item[$other_target], true);
if (ArrayHelper::check($other_targets))
{
$action_with_string = 0;
}
}
}
if ($action_with_string && JsonHelper::check($item['translation']))
{
$translation = json_decode((string) $item['translation'], true);
if (ArrayHelper::check($translation))
{
$this->update->set($item['id'], $targets, $targets, 2, $today, $counter);
$counter++;
$this->update->execute(50);
$action_with_string = 2;
}
}
if ($action_with_string == 1)
{
$this->removeExitingLangString($item['id']);
}
}
/**
* Remove existing language translation strings.
*
* This method deletes a language string from the database based on its ID.
*
* @param int $id The string ID to remove.
*
* @return void
* @since 5.0.2
*/
protected function removeExitingLangString(int $id): void
{
$query = $this->db->getQuery(true);
$query->delete($this->db->quoteName('#__componentbuilder_language_translation'))
->where($this->db->quoteName('id') . ' = ' . (int) $id);
$this->db->setQuery($query);
$this->db->execute();
}
}

View File

@ -0,0 +1,169 @@
/**
* The Update Class.
*
* @var Update
* @since 5.0.2
*/
protected Update $update;
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @param Update $update The Update Class.
*
* @since 5.0.2
*/
public function __construct(Update $update)
{
$this->update = $update;
$this->db = Factory::getDbo();
}
/**
* Purge the unused language strings.
*
* This method removes or updates language strings that are no longer linked
* to the specified component. It checks if the strings are linked to other
* extensions and either updates, archives, or deletes them based on the
* conditions.
*
* @param array $values The active strings.
* @param int $targetId The target component ID.
* @param string $target The target extension type (default is 'components').
*
* @return void
* @since 5.0.2
*/
public function execute(array $values, int $targetId, string $target = 'components'): void
{
$target_types = ['components' => 'components', 'modules' => 'modules', 'plugins' => 'plugins'];
if (isset($target_types[$target]))
{
unset($target_types[$target]);
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from($this->db->quoteName('#__componentbuilder_language_translation', 'a'))
->select($this->db->quoteName(['a.id', 'a.translation', 'a.components', 'a.modules', 'a.plugins']))
->where($this->db->quoteName('a.source') . ' NOT IN (' . implode(',', array_map(fn($a) => $this->db->quote($a), $values)) . ')')
->where($this->db->quoteName('a.published') . ' = 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
$counterUpdate = 0;
$otherStrings = $this->db->loadAssocList();
$today = Factory::getDate()->toSql();
foreach ($otherStrings as $item)
{
if (JsonHelper::check($item[$target]))
{
$targets = (array) json_decode((string) $item[$target], true);
if (($key = array_search($targetId, $targets)) !== false)
{
unset($targets[$key]);
if (ArrayHelper::check($targets))
{
$this->update->set($item['id'], $target, $targets, 1, $today, $counterUpdate);
$counterUpdate++;
$this->update->execute(50);
}
else
{
$this->handleUnlinkedString($item, $target_types, $targets, $today, $counterUpdate);
}
}
}
}
$this->update->execute();
}
}
}
/**
* Handle strings that are unlinked from the current component.
*
* This method checks if a string is linked to other extensions and either updates,
* archives, or deletes it based on the conditions.
*
* @param array $item The language string item.
* @param array $targetTypes The target extension types.
* @param array $targets The targets to update.
* @param string $today The current date.
* @param int $counter The update counter.
*
* @return void
* @since 5.0.2
*/
protected function handleUnlinkedString(array $item, array $targetTypes, array $targets, string $today, int &$counter): void
{
// the action (1 = remove, 2 = archive, 0 = do nothing)
$action_with_string = 1;
foreach ($targetTypes as $other_target)
{
if ($action_with_string && JsonHelper::check($item[$other_target]))
{
$other_targets = (array) json_decode((string) $item[$other_target], true);
if (ArrayHelper::check($other_targets))
{
$action_with_string = 0;
}
}
}
if ($action_with_string && JsonHelper::check($item['translation']))
{
$translation = json_decode((string) $item['translation'], true);
if (ArrayHelper::check($translation))
{
$this->update->set($item['id'], $targets, $targets, 2, $today, $counter);
$counter++;
$this->update->execute(50);
$action_with_string = 2;
}
}
if ($action_with_string == 1)
{
$this->removeExitingLangString($item['id']);
}
}
/**
* Remove existing language translation strings.
*
* This method deletes a language string from the database based on its ID.
*
* @param int $id The string ID to remove.
*
* @return void
* @since 5.0.2
*/
protected function removeExitingLangString(int $id): void
{
$query = $this->db->getQuery(true);
$query->delete($this->db->quoteName('#__componentbuilder_language_translation'))
->where($this->db->quoteName('id') . ' = ' . (int) $id);
$this->db->setQuery($query);
$this->db->execute();
}

View File

@ -0,0 +1,32 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "0b0e574c-aab4-4eaf-96d8-d7210d8ed93e",
"implements": null,
"load_selection": null,
"name": "Purge",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Language.Purge",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "375543cd-5f2a-4893-982e-a73eaa55360d",
"as": "default"
},
"use_selection1": {
"use": "4b225c51-d293-48e4-b3f6-5136cf5c3f18",
"as": "default"
},
"use_selection2": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Language.Purge",
"description": "Compiler Remove Existing Language Strings\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;",
"composer": ""
}

View File

@ -0,0 +1,95 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Data (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive**
```uml
@startuml
class Data << (F,LightGreen) >> #RoyalBlue {
# array $data
# Config $config
# Customcode $customcode
# Gui $gui
# Placeholder $placeholder
# Language $language
# Field $field
# FieldName $fieldname
# Filesfolders $filesfolders
# $db
+ __construct(Config $config, Customcode $customcode, ...)
+ get(int $id = null) : object|array|null
+ exists(int $id = null) : bool
+ set(int $id) : bool
}
note right of Data::__construct
Constructor.
since: 5.0.2
arguments:
Config $config
Customcode $customcode
Gui $gui
Placeholder $placeholder
Language $language
Field $field
FieldName $fieldname
Filesfolders $filesfolders
end note
note right of Data::get
Get the Joomla Plugin/s
since: 3.2.0
return: object|array|null
end note
note right of Data::exists
Check if the Joomla Plugin/s exists
since: 3.2.0
return: bool
end note
note right of Data::set
Set the Joomla Plugin
since: 3.2.0
return: bool
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---174f5c9c_5e03_4261_94ca_279ca76c710d---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,934 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive;
use Joomla\CMS\Factory;
use Joomla\CMS\Filter\OutputFilter;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Customcode;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Field;
use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName;
use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\String\ClassfunctionHelper;
use VDM\Joomla\Utilities\String\PluginHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\GetHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface;
/**
* Joomla 5 Plug-in Data Class
*
* @since 5.0.2
*/
final class Data implements PluginDataInterface
{
/**
* Compiler Joomla Plug-in's Data
*
* @var array
* @since 3.2.0
*/
protected array $data = [];
/**
* The Configure Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Customcode Class.
*
* @var Customcode
* @since 5.0.2
*/
protected Customcode $customcode;
/**
* The Gui Class.
*
* @var Gui
* @since 5.0.2
*/
protected Gui $gui;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Field Class.
*
* @var Field
* @since 5.0.2
*/
protected Field $field;
/**
* The Name Class.
*
* @var FieldName
* @since 5.0.2
*/
protected FieldName $fieldname;
/**
* The Filesfolders Class.
*
* @var Filesfolders
* @since 5.0.2
*/
protected Filesfolders $filesfolders;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Define the mappings of traits and classes to their respective methods and services
*
* @var array
* @since 5.0.2
**/
protected array $service_checks = [
'DatabaseAwareTrait' => [
'trait' => 'Joomla\Database\DatabaseAwareTrait',
'class' => 'Joomla__'.'_ae15e6b6_f7de_43ad_be4b_71499ae88f45___Power',
'method' => 'setDatabase',
'service' => 'Joomla__'.'_7bd29d76_73c9_4c07_a5da_4f7a32aff78f___Power'
],
'UserFactoryAwareTrait' => [
'trait' => 'Joomla\CMS\User\UserFactoryAwareTrait',
'class' => 'Joomla__'.'_a6b2c321_5de3_4425_b05f_e5340965fb80___Power',
'method' => 'setUserFactory',
'service' => 'Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power'
]
];
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Customcode $customcode The Customcode Class.
* @param Gui $gui The Gui Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Language Class.
* @param Field $field The Field Class.
* @param FieldName $fieldname The Name Class.
* @param Filesfolders $filesfolders The Filesfolders Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Customcode $customcode, Gui $gui,
Placeholder $placeholder, Language $language,
Field $field, FieldName $fieldname,
Filesfolders $filesfolders)
{
$this->config = $config;
$this->customcode = $customcode;
$this->gui = $gui;
$this->placeholder = $placeholder;
$this->language = $language;
$this->field = $field;
$this->fieldname = $fieldname;
$this->filesfolders = $filesfolders;
$this->db = Factory::getDbo();
}
/**
* Get the Joomla Plugin/s
*
* @param int|null $id the plugin id
*
* @return object|array|null if ID found it returns object, if no ID given it returns all set
* @since 3.2.0
*/
public function get(int $id = null)
{
if (is_null($id) && $this->exists())
{
return $this->data;
}
elseif ($this->exists($id))
{
return $this->data[$id];
}
return null;
}
/**
* Check if the Joomla Plugin/s exists
*
* @param int|null $id the plugin id
*
* @return bool if ID found it returns true, if no ID given it returns true if any are set
* @since 3.2.0
*/
public function exists(int $id = null): bool
{
if (is_null($id))
{
return ArrayHelper::check($this->data);
}
elseif (isset($this->data[$id]))
{
return true;
}
return $this->set($id);
}
/**
* Set the Joomla Plugin
*
* @param int $id the plugin id
*
* @return bool true on success
* @since 3.2.0
*/
public function set(int $id): bool
{
if (isset($this->data[$id]))
{
return true;
}
else
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->select('a.*');
$query->select(
$this->db->quoteName(
array(
'g.name',
'e.name',
'e.head',
'e.comment',
'e.id',
'f.addfiles',
'f.addfolders',
'f.addfilesfullpath',
'f.addfoldersfullpath',
'f.addurls',
'u.version_update',
'u.id'
), array(
'group',
'extends',
'class_head',
'comment',
'class_id',
'addfiles',
'addfolders',
'addfilesfullpath',
'addfoldersfullpath',
'addurls',
'version_update',
'version_update_id'
)
)
);
// from these tables
$query->from('#__componentbuilder_joomla_plugin AS a');
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_group', 'g'
) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group')
. ' = ' . $this->db->quoteName('g.id') . ')'
);
$query->join(
'LEFT',
$this->db->quoteName('#__componentbuilder_class_extends', 'e')
. ' ON (' . $this->db->quoteName('a.class_extends') . ' = '
. $this->db->quoteName('e.id') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_updates', 'u'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('u.joomla_plugin') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_files_folders_urls', 'f'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('f.joomla_plugin') . ')'
);
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
$query->where($this->db->quoteName('a.published') . ' >= 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
// get the plugin data
$plugin = $this->db->loadObject();
// tweak system to set stuff to the plugin domain
$_backup_target = $this->config->build_target;
$_backup_lang = $this->config->lang_target;
$_backup_langPrefix = $this->config->lang_prefix;
// set some keys
$plugin->target_type = 'pLuG!n';
$plugin->key = $plugin->id . '_' . $plugin->target_type;
// update to point to plugin
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
// set version if not set
if (empty($plugin->plugin_version))
{
$plugin->plugin_version = '1.0.0';
}
// set GUI mapper
$guiMapper = array('table' => 'joomla_plugin',
'id' => (int) $id, 'type' => 'php');
// update the name if it has dynamic values
$plugin->name = $this->placeholder->update_(
$this->customcode->update($plugin->name)
);
// update the name if it has dynamic values
$plugin->code_name
= ClassfunctionHelper::safe(
$plugin->name
);
// set official name
$plugin->official_name = ucwords(
$plugin->group . ' - ' . $plugin->name
);
// set lang prefix
$plugin->lang_prefix = PluginHelper::safeLangPrefix(
$plugin->code_name,
$plugin->group
);
// set langPrefix
$this->config->lang_prefix = $plugin->lang_prefix;
// set plugin class name
$plugin->class_name = ucfirst(
$plugin->code_name
);
// set plugin context name
$plugin->context_name = strtolower((string)
$plugin->code_name
);
// set plugin namespace
$plugin->namespace = $plugin->code_name;
// set plugin group namespace
$plugin->group_namespace = ucfirst(
$plugin->group
);
// set plugin install class name
$plugin->installer_class_name
= PluginHelper::safeInstallClassName(
$plugin->code_name,
$plugin->group
);
// set plugin folder name
$plugin->folder_name
= PluginHelper::safeFolderName(
$plugin->code_name,
$plugin->group
);
// set the zip name
$plugin->zip_name = $plugin->folder_name . '_v' . str_replace(
'.', '_', (string) $plugin->plugin_version
) . '__J' . $this->config->joomla_version;
// set plugin file name
$plugin->file_name = $plugin->context_name;
$plugin->class_file_name = $plugin->code_name;
// set plugin context
$plugin->context = $plugin->folder_name . '.' . $plugin->id;
// set official_name lang strings
$this->language->set(
$plugin->key, $this->config->lang_prefix, $plugin->official_name
);
// set some placeholder for this plugin
$this->placeholder->set('Plugin_name', $plugin->official_name);
$this->placeholder->set('PLUGIN_NAME', $plugin->official_name);
$this->placeholder->set('Plugin', ucfirst((string) $plugin->code_name));
$this->placeholder->set('plugin', strtolower((string) $plugin->code_name));
$this->placeholder->set('Plugin_group', ucfirst((string) $plugin->group));
$this->placeholder->set('plugin_group', strtolower((string) $plugin->group));
$this->placeholder->set('plugin.version', $plugin->plugin_version);
$this->placeholder->set('VERSION', $plugin->plugin_version);
$this->placeholder->set('plugin_version', str_replace(
'.', '_', (string) $plugin->plugin_version
));
// set description
$this->placeholder->set('DESCRIPTION', '');
if (!isset($plugin->description)
|| !StringHelper::check(
$plugin->description
))
{
$plugin->description = '';
}
else
{
$plugin->description = $this->placeholder->update_(
$this->customcode->update($plugin->description)
);
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_DESCRIPTION',
$plugin->description
);
// set description
$this->placeholder->set('DESCRIPTION', $plugin->description);
$plugin->description = '<p>' . $plugin->description . '</p>';
}
// get author name
$project_author = $this->config->project_author;
// we can only set these if the component was passed
$plugin->xml_description = "<h1>" . $plugin->official_name
. " (v." . $plugin->plugin_version
. ")</h1> <div style='clear: both;'></div>"
. $plugin->description . "<p>Created by <a href='" . trim(
(string) $this->config->project_website
) . "' target='_blank'>" . trim(
(string) OutputFilter::cleanText($project_author)
) . "</a><br /><small>Development started "
. Factory::getDate($plugin->created)->format("jS F, Y")
. "</small></p>";
// set xml discription
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_XML_DESCRIPTION',
$plugin->xml_description
);
// update the readme if set
if ($plugin->addreadme == 1 && !empty($plugin->readme))
{
$plugin->readme = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->readme))
);
}
else
{
$plugin->addreadme = 0;
unset($plugin->readme);
}
// open some base64 strings
if (!empty($plugin->main_class_code))
{
// set GUI mapper field
$guiMapper['field'] = 'main_class_code';
// base64 Decode main_class_code.
$plugin->main_class_code = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->main_class_code)
)
),
$guiMapper
);
}
// set the head :)
if ($plugin->add_head == 1 && !empty($plugin->head))
{
// set GUI mapper field
$guiMapper['field'] = 'head';
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->head)
)
),
$guiMapper
);
}
elseif (!empty($plugin->class_head))
{
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->class_head)
)
),
array(
'table' => 'class_extends',
'field' => 'head',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
unset($plugin->class_head);
// Check the plugin's code and header for each trait
foreach ($this->service_checks as $key => $info)
{
if (strpos($plugin->main_class_code, $key) !== false ||
strpos($plugin->main_class_code, $info['class']) !== false ||
strpos($plugin->header, $info['trait']) !== false)
{
$service_provider[] = Indent::_(4) . "\$plugin->{$info['method']}(\$container->get({$info['service']}::class));";
}
}
// Assign service provider if any services were added
if (!empty($service_provider))
{
$plugin->service_provider = implode(PHP_EOL, $service_provider);
}
// set the comment
if (!empty($plugin->comment))
{
// base64 Decode comment.
$plugin->comment = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->comment)
)
),
array(
'table' => 'class_extends',
'field' => 'comment',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
// start the config array
$plugin->config_fields = [];
// create the form arrays
$plugin->form_files = [];
$plugin->fieldsets_label = [];
$plugin->fieldsets_paths = [];
$plugin->add_rule_path = [];
$plugin->add_field_path = [];
// set global fields rule to default component path
$plugin->fields_rules_paths = 1;
// set the fields data
$plugin->fields = (isset($plugin->fields)
&& JsonHelper::check($plugin->fields))
? json_decode((string) $plugin->fields, true) : null;
if (ArrayHelper::check($plugin->fields))
{
// ket global key
$key = $plugin->key;
$dynamic_fields = array('fieldset' => 'basic',
'fields_name' => 'params',
'file' => 'config');
foreach ($plugin->fields as $n => &$form)
{
if (isset($form['fields'])
&& ArrayHelper::check(
$form['fields']
))
{
// make sure the dynamic_field is set to dynamic_value by default
foreach (
$dynamic_fields as $dynamic_field =>
$dynamic_value
)
{
if (!isset($form[$dynamic_field])
|| !StringHelper::check(
$form[$dynamic_field]
))
{
$form[$dynamic_field] = $dynamic_value;
}
else
{
if ('fields_name' === $dynamic_field
&& strpos((string) $form[$dynamic_field], '.')
!== false)
{
$form[$dynamic_field]
= $form[$dynamic_field];
}
else
{
$form[$dynamic_field]
= StringHelper::safe(
$form[$dynamic_field]
);
}
}
}
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// now build the form key
$unique = $form['file'] . $form['fields_name']
. $form['fieldset'];
}
else
{
// now build the form key
$unique = $form['fields_name']
. $form['fieldset'];
}
// set global fields rule path switchs
if ($plugin->fields_rules_paths == 1
&& isset($form['fields_rules_paths'])
&& $form['fields_rules_paths'] == 2)
{
$plugin->fields_rules_paths = 2;
}
// set where to path is pointing
$plugin->fieldsets_paths[$unique]
= $form['fields_rules_paths'];
// add the label if set to lang
if (isset($form['label'])
&& StringHelper::check(
$form['label']
))
{
$plugin->fieldsets_label[$unique]
= $this->language->key($form['label']);
}
// check for extra rule paths
if (isset($form['addrulepath'])
&& ArrayHelper::check($form['addrulepath']))
{
foreach ($form['addrulepath'] as $add_rule_path)
{
if (StringHelper::check($add_rule_path['path']))
{
$plugin->add_rule_path[$unique] = $add_rule_path['path'];
}
}
}
// check for extra field paths
if (isset($form['addfieldpath'])
&& ArrayHelper::check($form['addfieldpath']))
{
foreach ($form['addfieldpath'] as $add_field_path)
{
if (StringHelper::check($add_field_path['path']))
{
$plugin->add_field_path[$unique] = $add_field_path['path'];
}
}
}
// build the fields
$form['fields'] = array_map(
function ($field) use ($key, $unique) {
// make sure the alias and title is 0
$field['alias'] = 0;
$field['title'] = 0;
// set the field details
$this->field->set(
$field, $key, $key, $unique
);
// update the default if set
if (StringHelper::check(
$field['custom_value']
)
&& isset($field['settings']))
{
if (($old_default
= GetHelper::between(
$field['settings']->xml,
'default="', '"', false
)) !== false)
{
// replace old default
$field['settings']->xml
= str_replace(
'default="' . $old_default
. '"', 'default="'
. $field['custom_value'] . '"',
(string) $field['settings']->xml
);
}
else
{
// add the default (hmmm not ideal but okay it should work)
$field['settings']->xml
= 'default="'
. $field['custom_value'] . '" '
. $field['settings']->xml;
}
}
unset($field['custom_value']);
// return field
return $field;
}, array_values($form['fields'])
);
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// load the form file
if (!isset($plugin->form_files[$form['file']]))
{
$plugin->form_files[$form['file']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']]))
{
$plugin->form_files[$form['file']][$form['fields_name']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]))
{
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the global form file builder
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
else
{
// load the config form
if (!isset($plugin->config_fields[$form['fields_name']]))
{
$plugin->config_fields[$form['fields_name']]
= [];
}
if (!isset($plugin->config_fields[$form['fields_name']][$form['fieldset']]))
{
$plugin->config_fields[$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the config builder
$plugin->config_fields[$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
}
else
{
unset($plugin->fields[$n]);
}
}
}
unset($plugin->fields);
// set files and folders
$this->filesfolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method',
'php_script'
];
$addScriptTypes = [
'install',
'update',
'uninstall',
'construct'
];
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType})
&& $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$plugin->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $plugin->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
}
else
{
unset($plugin->{$scriptMethod . '_' . $scriptType});
$plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}
// add_sql
if ($plugin->add_sql == 1
&& StringHelper::check($plugin->sql))
{
$plugin->sql = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->sql))
);
}
else
{
unset($plugin->sql);
$plugin->add_sql = 0;
}
// add_sql_uninstall
if ($plugin->add_sql_uninstall == 1
&& StringHelper::check(
$plugin->sql_uninstall
))
{
$plugin->sql_uninstall = $this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->sql_uninstall)
)
);
}
else
{
unset($plugin->sql_uninstall);
$plugin->add_sql_uninstall = 0;
}
// update the URL of the update_server if set
if ($plugin->add_update_server == 1
&& StringHelper::check(
$plugin->update_server_url
))
{
$plugin->update_server_url = $this->placeholder->update_(
$this->customcode->update($plugin->update_server_url)
);
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($plugin->{'add_' . $server} == 1
&& is_numeric(
$plugin->{$server}
)
&& $plugin->{$server} > 0)
{
// get the server protocol
$plugin->{$server . '_protocol'}
= GetHelper::var(
'server', (int) $plugin->{$server}, 'id', 'protocol'
);
}
else
{
$plugin->{$server} = 0;
// only change this for sales server (update server can be added locally to the zip file)
if ('sales_server' === $server)
{
$plugin->{'add_' . $server} = 0;
}
$plugin->{$server . '_protocol'} = 0;
}
}
// old path (to remove)
$plugin->remove_file_paths = [];
$plugin->remove_file_paths[] = "/plugins/{$plugin->group}/{$plugin->context_name}/{$plugin->file_name}.php";
// set the update server stuff (TODO)
// update_server_xml_path
// update_server_xml_file_name
// rest globals
$this->config->build_target = $_backup_target;
$this->config->lang_target = $_backup_lang;
$this->config->set('lang_prefix', $_backup_langPrefix);
$this->placeholder->remove('Plugin_name');
$this->placeholder->remove('Plugin');
$this->placeholder->remove('plugin');
$this->placeholder->remove('Plugin_group');
$this->placeholder->remove('plugin_group');
$this->placeholder->remove('plugin.version');
$this->placeholder->remove('plugin_version');
$this->placeholder->remove('VERSION');
$this->placeholder->remove('DESCRIPTION');
$this->placeholder->remove('PLUGIN_NAME');
$this->data[$id] = $plugin;
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,891 @@
/**
* Compiler Joomla Plug-in's Data
*
* @var array
* @since 3.2.0
*/
protected array $data = [];
/**
* The Configure Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Customcode Class.
*
* @var Customcode
* @since 5.0.2
*/
protected Customcode $customcode;
/**
* The Gui Class.
*
* @var Gui
* @since 5.0.2
*/
protected Gui $gui;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Field Class.
*
* @var Field
* @since 5.0.2
*/
protected Field $field;
/**
* The Name Class.
*
* @var FieldName
* @since 5.0.2
*/
protected FieldName $fieldname;
/**
* The Filesfolders Class.
*
* @var Filesfolders
* @since 5.0.2
*/
protected Filesfolders $filesfolders;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Define the mappings of traits and classes to their respective methods and services
*
* @var array
* @since 5.0.2
**/
protected array $service_checks = [
'DatabaseAwareTrait' => [
'trait' => 'Joomla\Database\DatabaseAwareTrait',
'class' => 'Joomla__'.'_ae15e6b6_f7de_43ad_be4b_71499ae88f45___Power',
'method' => 'setDatabase',
'service' => 'Joomla__'.'_7bd29d76_73c9_4c07_a5da_4f7a32aff78f___Power'
],
'UserFactoryAwareTrait' => [
'trait' => 'Joomla\CMS\User\UserFactoryAwareTrait',
'class' => 'Joomla__'.'_a6b2c321_5de3_4425_b05f_e5340965fb80___Power',
'method' => 'setUserFactory',
'service' => 'Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power'
]
];
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Customcode $customcode The Customcode Class.
* @param Gui $gui The Gui Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Language Class.
* @param Field $field The Field Class.
* @param FieldName $fieldname The Name Class.
* @param Filesfolders $filesfolders The Filesfolders Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Customcode $customcode, Gui $gui,
Placeholder $placeholder, Language $language,
Field $field, FieldName $fieldname,
Filesfolders $filesfolders)
{
$this->config = $config;
$this->customcode = $customcode;
$this->gui = $gui;
$this->placeholder = $placeholder;
$this->language = $language;
$this->field = $field;
$this->fieldname = $fieldname;
$this->filesfolders = $filesfolders;
$this->db = Factory::getDbo();
}
/**
* Get the Joomla Plugin/s
*
* @param int|null $id the plugin id
*
* @return object|array|null if ID found it returns object, if no ID given it returns all set
* @since 3.2.0
*/
public function get(int $id = null)
{
if (is_null($id) && $this->exists())
{
return $this->data;
}
elseif ($this->exists($id))
{
return $this->data[$id];
}
return null;
}
/**
* Check if the Joomla Plugin/s exists
*
* @param int|null $id the plugin id
*
* @return bool if ID found it returns true, if no ID given it returns true if any are set
* @since 3.2.0
*/
public function exists(int $id = null): bool
{
if (is_null($id))
{
return ArrayHelper::check($this->data);
}
elseif (isset($this->data[$id]))
{
return true;
}
return $this->set($id);
}
/**
* Set the Joomla Plugin
*
* @param int $id the plugin id
*
* @return bool true on success
* @since 3.2.0
*/
public function set(int $id): bool
{
if (isset($this->data[$id]))
{
return true;
}
else
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->select('a.*');
$query->select(
$this->db->quoteName(
array(
'g.name',
'e.name',
'e.head',
'e.comment',
'e.id',
'f.addfiles',
'f.addfolders',
'f.addfilesfullpath',
'f.addfoldersfullpath',
'f.addurls',
'u.version_update',
'u.id'
), array(
'group',
'extends',
'class_head',
'comment',
'class_id',
'addfiles',
'addfolders',
'addfilesfullpath',
'addfoldersfullpath',
'addurls',
'version_update',
'version_update_id'
)
)
);
// from these tables
$query->from('#__componentbuilder_joomla_plugin AS a');
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_group', 'g'
) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group')
. ' = ' . $this->db->quoteName('g.id') . ')'
);
$query->join(
'LEFT',
$this->db->quoteName('#__componentbuilder_class_extends', 'e')
. ' ON (' . $this->db->quoteName('a.class_extends') . ' = '
. $this->db->quoteName('e.id') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_updates', 'u'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('u.joomla_plugin') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_files_folders_urls', 'f'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('f.joomla_plugin') . ')'
);
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
$query->where($this->db->quoteName('a.published') . ' >= 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
// get the plugin data
$plugin = $this->db->loadObject();
// tweak system to set stuff to the plugin domain
$_backup_target = $this->config->build_target;
$_backup_lang = $this->config->lang_target;
$_backup_langPrefix = $this->config->lang_prefix;
// set some keys
$plugin->target_type = 'pLuG!n';
$plugin->key = $plugin->id . '_' . $plugin->target_type;
// update to point to plugin
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
// set version if not set
if (empty($plugin->plugin_version))
{
$plugin->plugin_version = '1.0.0';
}
// set GUI mapper
$guiMapper = array('table' => 'joomla_plugin',
'id' => (int) $id, 'type' => 'php');
// update the name if it has dynamic values
$plugin->name = $this->placeholder->update_(
$this->customcode->update($plugin->name)
);
// update the name if it has dynamic values
$plugin->code_name
= ClassfunctionHelper::safe(
$plugin->name
);
// set official name
$plugin->official_name = ucwords(
$plugin->group . ' - ' . $plugin->name
);
// set lang prefix
$plugin->lang_prefix = PluginHelper::safeLangPrefix(
$plugin->code_name,
$plugin->group
);
// set langPrefix
$this->config->lang_prefix = $plugin->lang_prefix;
// set plugin class name
$plugin->class_name = ucfirst(
$plugin->code_name
);
// set plugin context name
$plugin->context_name = strtolower((string)
$plugin->code_name
);
// set plugin namespace
$plugin->namespace = $plugin->code_name;
// set plugin group namespace
$plugin->group_namespace = ucfirst(
$plugin->group
);
// set plugin install class name
$plugin->installer_class_name
= PluginHelper::safeInstallClassName(
$plugin->code_name,
$plugin->group
);
// set plugin folder name
$plugin->folder_name
= PluginHelper::safeFolderName(
$plugin->code_name,
$plugin->group
);
// set the zip name
$plugin->zip_name = $plugin->folder_name . '_v' . str_replace(
'.', '_', (string) $plugin->plugin_version
) . '__J' . $this->config->joomla_version;
// set plugin file name
$plugin->file_name = $plugin->context_name;
$plugin->class_file_name = $plugin->code_name;
// set plugin context
$plugin->context = $plugin->folder_name . '.' . $plugin->id;
// set official_name lang strings
$this->language->set(
$plugin->key, $this->config->lang_prefix, $plugin->official_name
);
// set some placeholder for this plugin
$this->placeholder->set('Plugin_name', $plugin->official_name);
$this->placeholder->set('PLUGIN_NAME', $plugin->official_name);
$this->placeholder->set('Plugin', ucfirst((string) $plugin->code_name));
$this->placeholder->set('plugin', strtolower((string) $plugin->code_name));
$this->placeholder->set('Plugin_group', ucfirst((string) $plugin->group));
$this->placeholder->set('plugin_group', strtolower((string) $plugin->group));
$this->placeholder->set('plugin.version', $plugin->plugin_version);
$this->placeholder->set('VERSION', $plugin->plugin_version);
$this->placeholder->set('plugin_version', str_replace(
'.', '_', (string) $plugin->plugin_version
));
// set description
$this->placeholder->set('DESCRIPTION', '');
if (!isset($plugin->description)
|| !StringHelper::check(
$plugin->description
))
{
$plugin->description = '';
}
else
{
$plugin->description = $this->placeholder->update_(
$this->customcode->update($plugin->description)
);
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_DESCRIPTION',
$plugin->description
);
// set description
$this->placeholder->set('DESCRIPTION', $plugin->description);
$plugin->description = '<p>' . $plugin->description . '</p>';
}
// get author name
$project_author = $this->config->project_author;
// we can only set these if the component was passed
$plugin->xml_description = "<h1>" . $plugin->official_name
. " (v." . $plugin->plugin_version
. ")</h1> <div style='clear: both;'></div>"
. $plugin->description . "<p>Created by <a href='" . trim(
(string) $this->config->project_website
) . "' target='_blank'>" . trim(
(string) OutputFilter::cleanText($project_author)
) . "</a><br /><small>Development started "
. Factory::getDate($plugin->created)->format("jS F, Y")
. "</small></p>";
// set xml discription
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_XML_DESCRIPTION',
$plugin->xml_description
);
// update the readme if set
if ($plugin->addreadme == 1 && !empty($plugin->readme))
{
$plugin->readme = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->readme))
);
}
else
{
$plugin->addreadme = 0;
unset($plugin->readme);
}
// open some base64 strings
if (!empty($plugin->main_class_code))
{
// set GUI mapper field
$guiMapper['field'] = 'main_class_code';
// base64 Decode main_class_code.
$plugin->main_class_code = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->main_class_code)
)
),
$guiMapper
);
}
// set the head :)
if ($plugin->add_head == 1 && !empty($plugin->head))
{
// set GUI mapper field
$guiMapper['field'] = 'head';
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->head)
)
),
$guiMapper
);
}
elseif (!empty($plugin->class_head))
{
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->class_head)
)
),
array(
'table' => 'class_extends',
'field' => 'head',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
unset($plugin->class_head);
// Check the plugin's code and header for each trait
foreach ($this->service_checks as $key => $info)
{
if (strpos($plugin->main_class_code, $key) !== false ||
strpos($plugin->main_class_code, $info['class']) !== false ||
strpos($plugin->header, $info['trait']) !== false)
{
$service_provider[] = Indent::_(4) . "\$plugin->{$info['method']}(\$container->get({$info['service']}::class));";
}
}
// Assign service provider if any services were added
if (!empty($service_provider))
{
$plugin->service_provider = implode(PHP_EOL, $service_provider);
}
// set the comment
if (!empty($plugin->comment))
{
// base64 Decode comment.
$plugin->comment = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->comment)
)
),
array(
'table' => 'class_extends',
'field' => 'comment',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
// start the config array
$plugin->config_fields = [];
// create the form arrays
$plugin->form_files = [];
$plugin->fieldsets_label = [];
$plugin->fieldsets_paths = [];
$plugin->add_rule_path = [];
$plugin->add_field_path = [];
// set global fields rule to default component path
$plugin->fields_rules_paths = 1;
// set the fields data
$plugin->fields = (isset($plugin->fields)
&& JsonHelper::check($plugin->fields))
? json_decode((string) $plugin->fields, true) : null;
if (ArrayHelper::check($plugin->fields))
{
// ket global key
$key = $plugin->key;
$dynamic_fields = array('fieldset' => 'basic',
'fields_name' => 'params',
'file' => 'config');
foreach ($plugin->fields as $n => &$form)
{
if (isset($form['fields'])
&& ArrayHelper::check(
$form['fields']
))
{
// make sure the dynamic_field is set to dynamic_value by default
foreach (
$dynamic_fields as $dynamic_field =>
$dynamic_value
)
{
if (!isset($form[$dynamic_field])
|| !StringHelper::check(
$form[$dynamic_field]
))
{
$form[$dynamic_field] = $dynamic_value;
}
else
{
if ('fields_name' === $dynamic_field
&& strpos((string) $form[$dynamic_field], '.')
!== false)
{
$form[$dynamic_field]
= $form[$dynamic_field];
}
else
{
$form[$dynamic_field]
= StringHelper::safe(
$form[$dynamic_field]
);
}
}
}
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// now build the form key
$unique = $form['file'] . $form['fields_name']
. $form['fieldset'];
}
else
{
// now build the form key
$unique = $form['fields_name']
. $form['fieldset'];
}
// set global fields rule path switchs
if ($plugin->fields_rules_paths == 1
&& isset($form['fields_rules_paths'])
&& $form['fields_rules_paths'] == 2)
{
$plugin->fields_rules_paths = 2;
}
// set where to path is pointing
$plugin->fieldsets_paths[$unique]
= $form['fields_rules_paths'];
// add the label if set to lang
if (isset($form['label'])
&& StringHelper::check(
$form['label']
))
{
$plugin->fieldsets_label[$unique]
= $this->language->key($form['label']);
}
// check for extra rule paths
if (isset($form['addrulepath'])
&& ArrayHelper::check($form['addrulepath']))
{
foreach ($form['addrulepath'] as $add_rule_path)
{
if (StringHelper::check($add_rule_path['path']))
{
$plugin->add_rule_path[$unique] = $add_rule_path['path'];
}
}
}
// check for extra field paths
if (isset($form['addfieldpath'])
&& ArrayHelper::check($form['addfieldpath']))
{
foreach ($form['addfieldpath'] as $add_field_path)
{
if (StringHelper::check($add_field_path['path']))
{
$plugin->add_field_path[$unique] = $add_field_path['path'];
}
}
}
// build the fields
$form['fields'] = array_map(
function ($field) use ($key, $unique) {
// make sure the alias and title is 0
$field['alias'] = 0;
$field['title'] = 0;
// set the field details
$this->field->set(
$field, $key, $key, $unique
);
// update the default if set
if (StringHelper::check(
$field['custom_value']
)
&& isset($field['settings']))
{
if (($old_default
= GetHelper::between(
$field['settings']->xml,
'default="', '"', false
)) !== false)
{
// replace old default
$field['settings']->xml
= str_replace(
'default="' . $old_default
. '"', 'default="'
. $field['custom_value'] . '"',
(string) $field['settings']->xml
);
}
else
{
// add the default (hmmm not ideal but okay it should work)
$field['settings']->xml
= 'default="'
. $field['custom_value'] . '" '
. $field['settings']->xml;
}
}
unset($field['custom_value']);
// return field
return $field;
}, array_values($form['fields'])
);
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// load the form file
if (!isset($plugin->form_files[$form['file']]))
{
$plugin->form_files[$form['file']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']]))
{
$plugin->form_files[$form['file']][$form['fields_name']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]))
{
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the global form file builder
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
else
{
// load the config form
if (!isset($plugin->config_fields[$form['fields_name']]))
{
$plugin->config_fields[$form['fields_name']]
= [];
}
if (!isset($plugin->config_fields[$form['fields_name']][$form['fieldset']]))
{
$plugin->config_fields[$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the config builder
$plugin->config_fields[$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
}
else
{
unset($plugin->fields[$n]);
}
}
}
unset($plugin->fields);
// set files and folders
$this->filesfolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method',
'php_script'
];
$addScriptTypes = [
'install',
'update',
'uninstall',
'construct'
];
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType})
&& $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$plugin->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $plugin->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
}
else
{
unset($plugin->{$scriptMethod . '_' . $scriptType});
$plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}
// add_sql
if ($plugin->add_sql == 1
&& StringHelper::check($plugin->sql))
{
$plugin->sql = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->sql))
);
}
else
{
unset($plugin->sql);
$plugin->add_sql = 0;
}
// add_sql_uninstall
if ($plugin->add_sql_uninstall == 1
&& StringHelper::check(
$plugin->sql_uninstall
))
{
$plugin->sql_uninstall = $this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->sql_uninstall)
)
);
}
else
{
unset($plugin->sql_uninstall);
$plugin->add_sql_uninstall = 0;
}
// update the URL of the update_server if set
if ($plugin->add_update_server == 1
&& StringHelper::check(
$plugin->update_server_url
))
{
$plugin->update_server_url = $this->placeholder->update_(
$this->customcode->update($plugin->update_server_url)
);
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($plugin->{'add_' . $server} == 1
&& is_numeric(
$plugin->{$server}
)
&& $plugin->{$server} > 0)
{
// get the server protocol
$plugin->{$server . '_protocol'}
= GetHelper::var(
'server', (int) $plugin->{$server}, 'id', 'protocol'
);
}
else
{
$plugin->{$server} = 0;
// only change this for sales server (update server can be added locally to the zip file)
if ('sales_server' === $server)
{
$plugin->{'add_' . $server} = 0;
}
$plugin->{$server . '_protocol'} = 0;
}
}
// old path (to remove)
$plugin->remove_file_paths = [];
$plugin->remove_file_paths[] = "/plugins/{$plugin->group}/{$plugin->context_name}/{$plugin->file_name}.php";
// set the update server stuff (TODO)
// update_server_xml_path
// update_server_xml_file_name
// rest globals
$this->config->build_target = $_backup_target;
$this->config->lang_target = $_backup_lang;
$this->config->set('lang_prefix', $_backup_langPrefix);
$this->placeholder->remove('Plugin_name');
$this->placeholder->remove('Plugin');
$this->placeholder->remove('plugin');
$this->placeholder->remove('Plugin_group');
$this->placeholder->remove('plugin_group');
$this->placeholder->remove('plugin.version');
$this->placeholder->remove('plugin_version');
$this->placeholder->remove('VERSION');
$this->placeholder->remove('DESCRIPTION');
$this->placeholder->remove('PLUGIN_NAME');
$this->data[$id] = $plugin;
return true;
}
}
return false;
}

View File

@ -0,0 +1,82 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "174f5c9c-5e03-4261-94ca-279ca76c710d",
"implements": [
"8cc85656-a925-4a46-a49b-83c72167fd6a"
],
"load_selection": null,
"name": "Data",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Joomlaplugin.J5.Data",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",
"as": "default"
},
"use_selection1": {
"use": "313b43c4-98c3-4f62-9177-2d73ec8eba31",
"as": "default"
},
"use_selection2": {
"use": "1bd48df2-4f7e-4581-9fe9-4b54e59105e3",
"as": "default"
},
"use_selection3": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection4": {
"use": "8eee7df5-2775-41a9-9372-c46c5939a252",
"as": "default"
},
"use_selection5": {
"use": "d7ba2d5d-10b6-470d-978d-9f91ea65ee75",
"as": "default"
},
"use_selection6": {
"use": "9387215f-a965-4421-acf3-5e8f9d11382f",
"as": "FieldName"
},
"use_selection7": {
"use": "f4578c04-a81e-4218-b80d-b0612196eaf0",
"as": "default"
},
"use_selection8": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
},
"use_selection9": {
"use": "30c5b4c2-f75f-4d15-869a-f8bfedd87358",
"as": "default"
},
"use_selection10": {
"use": "3cf76fbf-fd95-4a33-878e-7aff6d36b7f6",
"as": "default"
},
"use_selection11": {
"use": "4b225c51-d293-48e4-b3f6-5136cf5c3f18",
"as": "default"
},
"use_selection12": {
"use": "1f28cb53-60d9-4db1-b517-3c7dc6b429ef",
"as": "default"
},
"use_selection13": {
"use": "db87c339-5bb6-4291-a7ef-2c48ea1b06bc",
"as": "default"
},
"use_selection14": {
"use": "a68c010b-e92e-47d5-8a44-d23cfddeb6c6",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Joomlaplugin.JoomlaFive.Data",
"description": "Joomla 5 Plug-in Data Class\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;\r\nuse Joomla\\CMS\\Filter\\OutputFilter;",
"composer": ""
}

View File

@ -0,0 +1,80 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Insert (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Language**
```uml
@startuml
class Insert << (F,LightGreen) >> #RoyalBlue {
# array $items
# $db
+ __construct()
+ set(string $target, int $counter, ...) : void
+ execute(string $target, int $when = 1) : void
}
note right of Insert::__construct
Constructor.
since: 5.0.2
end note
note right of Insert::set
Sets a value in a multi-dimensional array within the `items` property.
This method ensures that the array structure is properly initialized before
inserting the value at the specified target and counter position.
since: 5.0.2
return: void
arguments:
string $target
int $counter
string $value
end note
note right of Insert::execute
Store the language placeholders and execute the database insert operation.
This method checks if the target key exists in the `items` array and if the count
of its elements meets or exceeds the specified threshold (`$when`). If the conditions
are met, it constructs and executes a database insert query to store the language
placeholders. The array of items for the target is then cleared.
since: 5.0.2
return: void
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---1d051a2f_0691_45a8_b3d9_d0c1adcd73bc---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,138 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
/**
* Compiler Insert New Language Strings
*
* @since 5.0.2
*/
final class Insert
{
/**
* The items to insert
*
* @var array
* @since 5.0.2
**/
protected array $items = [];
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
}
/**
* Sets a value in a multi-dimensional array within the `items` property.
*
* This method ensures that the array structure is properly initialized before
* inserting the value at the specified target and counter position.
*
* @param string $target The key in the first dimension of the array.
* @param int $counter The key in the second dimension of the array.
* @param string $value The value to be inserted.
*
* @return void
* @since 5.0.2
*/
public function set(string $target, int $counter, string $value): void
{
// Ensure the target key exists in the items array
if (!isset($this->items[$target]))
{
$this->items[$target] = [];
}
// Ensure the counter key exists within the target array
if (!isset($this->items[$target][$counter]))
{
$this->items[$target][$counter] = [];
}
// Append the value to the array at the specified target and counter position
$this->items[$target][$counter][] = $this->db->quote($value);
}
/**
* Store the language placeholders and execute the database insert operation.
*
* This method checks if the target key exists in the `items` array and if the count
* of its elements meets or exceeds the specified threshold (`$when`). If the conditions
* are met, it constructs and executes a database insert query to store the language
* placeholders. The array of items for the target is then cleared.
*
* @param string $target The target extension type.
* @param int $when The threshold count to determine when to update. Default is 1.
*
* @return void
* @since 5.0.2
*/
public function execute(string $target, int $when = 1): void
{
if (isset($this->items[$target]) && count((array) $this->items[$target]) >= $when)
{
// Create a new query object.
$query = $this->db->getQuery(true);
$continue = false;
// Insert columns.
$columns = array($target, 'source', 'published', 'created', 'created_by', 'version', 'access');
// Prepare the insert query.
$query->insert($this->db->quoteName('#__componentbuilder_language_translation'));
$query->columns($this->db->quoteName($columns));
foreach ($this->items[$target] as $values)
{
if (count((array) $values) == 7)
{
$query->values(implode(',', $values));
$continue = true;
}
else
{
// TODO: Handle line mismatch, this should not happen.
}
}
// Clear the values array.
$this->items[$target] = [];
if (!$continue)
{
// Ensure we don't continue if no values were loaded.
return;
}
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
}
}

View File

@ -0,0 +1,112 @@
/**
* The items to insert
*
* @var array
* @since 5.0.2
**/
protected array $items = [];
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
}
/**
* Sets a value in a multi-dimensional array within the `items` property.
*
* This method ensures that the array structure is properly initialized before
* inserting the value at the specified target and counter position.
*
* @param string $target The key in the first dimension of the array.
* @param int $counter The key in the second dimension of the array.
* @param string $value The value to be inserted.
*
* @return void
* @since 5.0.2
*/
public function set(string $target, int $counter, string $value): void
{
// Ensure the target key exists in the items array
if (!isset($this->items[$target]))
{
$this->items[$target] = [];
}
// Ensure the counter key exists within the target array
if (!isset($this->items[$target][$counter]))
{
$this->items[$target][$counter] = [];
}
// Append the value to the array at the specified target and counter position
$this->items[$target][$counter][] = $this->db->quote($value);
}
/**
* Store the language placeholders and execute the database insert operation.
*
* This method checks if the target key exists in the `items` array and if the count
* of its elements meets or exceeds the specified threshold (`$when`). If the conditions
* are met, it constructs and executes a database insert query to store the language
* placeholders. The array of items for the target is then cleared.
*
* @param string $target The target extension type.
* @param int $when The threshold count to determine when to update. Default is 1.
*
* @return void
* @since 5.0.2
*/
public function execute(string $target, int $when = 1): void
{
if (isset($this->items[$target]) && count((array) $this->items[$target]) >= $when)
{
// Create a new query object.
$query = $this->db->getQuery(true);
$continue = false;
// Insert columns.
$columns = array($target, 'source', 'published', 'created', 'created_by', 'version', 'access');
// Prepare the insert query.
$query->insert($this->db->quoteName('#__componentbuilder_language_translation'));
$query->columns($this->db->quoteName($columns));
foreach ($this->items[$target] as $values)
{
if (count((array) $values) == 7)
{
$query->values(implode(',', $values));
$continue = true;
}
else
{
// TODO: Handle line mismatch, this should not happen.
}
}
// Clear the values array.
$this->items[$target] = [];
if (!$continue)
{
// Ensure we don't continue if no values were loaded.
return;
}
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
}

View File

@ -0,0 +1,19 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "1d051a2f-0691-45a8-b3d9-d0c1adcd73bc",
"implements": null,
"load_selection": null,
"name": "Insert",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Language.Insert",
"type": "final class",
"use_selection": null,
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Language.Insert",
"description": "Compiler Insert New Language Strings\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;",
"composer": ""
}

View File

@ -29,7 +29,6 @@ class Header << (F,LightGreen) >> #RoyalBlue {
+ __construct(Config $config, Event $event, ...)
+ get(string $context, string $codeName) : string
# getHeaders(string $context) : array
# setHelperClassHeader(array $headers, string $target_client) : void
}
note right of Header::__construct
@ -63,13 +62,6 @@ note right of Header::getHeaders
since: 3.2.0
return: array
end note
note right of Header::setHelperClassHeader
set Helper Dynamic Headers
since: 3.2.0
return: void
end note
@enduml
```

View File

@ -228,11 +228,6 @@ final class Header implements HeaderInterface
// get dynamic headers
switch ($context)
{
case 'admin.helper':
case 'site.helper':
$this->setHelperClassHeader($headers, $codeName);
break;
case 'admin.view.html':
case 'admin.views.html':
case 'custom.admin.view.html':
@ -267,6 +262,10 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Helper\TagsHelper;';
break;
case 'plugin.provider.header':
$headers[] = "use {$this->NamespacePrefix}\\Plugin\\[[[PluginGroupNamespace]]]\\[[[PluginNamespace]]]\\Extension\\{$codeName};";
break;
default:
break;
}
@ -553,6 +552,33 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Form\Field\###FORM_EXTENDS###;';
break;
case 'plugin.extension.header':
$headers = [];
break;
case 'plugin.provider.header':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\Plugin\PluginHelper;';
$headers[] = 'use Joomla\CMS\Extension\PluginInterface;';
$headers[] = 'use Joomla\Event\DispatcherInterface;';
$headers[] = 'use Joomla\DI\ServiceProviderInterface;';
$headers[] = 'use Joomla\DI\Container;';
break;
case 'api.view.controller':
case 'api.views.controller':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\MVC\Controller\ApiController;';
break;
case 'api.view.json':
case 'api.views.json':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\MVC\View\JsonApiView as BaseApiView;';
break;
default:
break;
}
@ -560,26 +586,6 @@ final class Header implements HeaderInterface
$this->headers[$context] = $headers;
return $headers;
}
/**
* set Helper Dynamic Headers
*
* @param array $headers The headers array
* @param string $target_client
*
* @return void
* @since 3.2.0
*/
protected function setHelperClassHeader(&$headers, $target_client)
{
// add only to admin client
if ('admin' === $target_client && $this->config->get('add_eximport', false))
{
$headers[] = 'use PhpOffice\PhpSpreadsheet\IOFactory;';
$headers[] = 'use PhpOffice\PhpSpreadsheet\Spreadsheet;';
$headers[] = 'use PhpOffice\PhpSpreadsheet\Writer\Xlsx;';
}
}
}

View File

@ -192,11 +192,6 @@
// get dynamic headers
switch ($context)
{
case 'admin.helper':
case 'site.helper':
$this->setHelperClassHeader($headers, $codeName);
break;
case 'admin.view.html':
case 'admin.views.html':
case 'custom.admin.view.html':
@ -231,6 +226,10 @@
$headers[] = 'use Joomla\CMS\Helper\TagsHelper;';
break;
case 'plugin.provider.header':
$headers[] = "use {$this->NamespacePrefix}\\Plugin\\[[[PluginGroupNamespace]]]\\[[[PluginNamespace]]]\\Extension\\{$codeName};";
break;
default:
break;
}
@ -517,6 +516,33 @@
$headers[] = 'use Joomla\CMS\Form\Field\###FORM_EXTENDS###;';
break;
case 'plugin.extension.header':
$headers = [];
break;
case 'plugin.provider.header':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\Plugin\PluginHelper;';
$headers[] = 'use Joomla\CMS\Extension\PluginInterface;';
$headers[] = 'use Joomla\Event\DispatcherInterface;';
$headers[] = 'use Joomla\DI\ServiceProviderInterface;';
$headers[] = 'use Joomla\DI\Container;';
break;
case 'api.view.controller':
case 'api.views.controller':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\MVC\Controller\ApiController;';
break;
case 'api.view.json':
case 'api.views.json':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\MVC\View\JsonApiView as BaseApiView;';
break;
default:
break;
}
@ -524,24 +550,4 @@
$this->headers[$context] = $headers;
return $headers;
}
/**
* set Helper Dynamic Headers
*
* @param array $headers The headers array
* @param string $target_client
*
* @return void
* @since 3.2.0
*/
protected function setHelperClassHeader(&$headers, $target_client)
{
// add only to admin client
if ('admin' === $target_client && $this->config->get('add_eximport', false))
{
$headers[] = 'use PhpOffice\PhpSpreadsheet\IOFactory;';
$headers[] = 'use PhpOffice\PhpSpreadsheet\Spreadsheet;';
$headers[] = 'use PhpOffice\PhpSpreadsheet\Writer\Xlsx;';
}
}

View File

@ -0,0 +1,66 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class FieldsetExtension (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Creator**
```uml
@startuml
class FieldsetExtension << (F,LightGreen) >> #RoyalBlue {
# Placeholder $placeholder
# FieldsetDynamic $fieldsetdynamic
+ __construct(Placeholder $placeholder, FieldsetDynamic $fieldsetdynamic)
+ get(object $extension, array $fields, ...) : string
}
note right of FieldsetExtension::__construct
Constructor.
since: 5.0.2
end note
note right of FieldsetExtension::get
build field set for an extention
since: 5.0.2
return: string
arguments:
object $extension
array $fields
string $dbkey = 'zz'
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---23f459a4_7c2a_4cbf_b0a6_8a11954140a9---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,78 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Creator;
use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetDynamic;
/**
* Extension Fieldset Creator Class
*
* @since 5.0.2
*/
final class FieldsetExtension
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The FieldsetDynamic Class.
*
* @var FieldsetDynamic
* @since 5.0.2
*/
protected FieldsetDynamic $fieldsetdynamic;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param FieldsetDynamic $fieldsetdynamic The Fieldset Dynamic Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, FieldsetDynamic $fieldsetdynamic)
{
$this->placeholder = $placeholder;
$this->fieldsetdynamic = $fieldsetdynamic;
}
/**
* build field set for an extention
*
* @param object $extension The extention object
* @param array $fields The fields to build
* @param string $dbkey The database key
*
* @return string The fields set in xml
*
* @since 5.0.2
*/
public function get(object $extension, array $fields, string $dbkey = 'zz'): string
{
// get global placeholders
$placeholder = $this->placeholder->get();
// build the fieldset
return $this->fieldsetdynamic->get(
$fields, $extension->lang_prefix, $extension->key, $extension->key,
$placeholder, $dbkey
);
}
}

View File

@ -0,0 +1,51 @@
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The FieldsetDynamic Class.
*
* @var FieldsetDynamic
* @since 5.0.2
*/
protected FieldsetDynamic $fieldsetdynamic;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param FieldsetDynamic $fieldsetdynamic The Fieldset Dynamic Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, FieldsetDynamic $fieldsetdynamic)
{
$this->placeholder = $placeholder;
$this->fieldsetdynamic = $fieldsetdynamic;
}
/**
* build field set for an extention
*
* @param object $extension The extention object
* @param array $fields The fields to build
* @param string $dbkey The database key
*
* @return string The fields set in xml
*
* @since 5.0.2
*/
public function get(object $extension, array $fields, string $dbkey = 'zz'): string
{
// get global placeholders
$placeholder = $this->placeholder->get();
// build the fieldset
return $this->fieldsetdynamic->get(
$fields, $extension->lang_prefix, $extension->key, $extension->key,
$placeholder, $dbkey
);
}

View File

@ -0,0 +1,28 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "23f459a4-7c2a-4cbf-b0a6-8a11954140a9",
"implements": null,
"load_selection": null,
"name": "FieldsetExtension",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Creator.FieldsetExtension",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "aecc17ba-0b0f-4e5c-ae43-71be063a3dcb",
"as": "default"
},
"use_selection1": {
"use": "b5986fab-17ca-4236-8c0c-81ebd2bb82ba",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Creator.FieldsetExtension",
"description": "Extension Fieldset Creator Class\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -0,0 +1,60 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Multilingual (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Language**
```uml
@startuml
class Multilingual << (F,LightGreen) >> #RoyalBlue {
# $db
+ __construct()
+ get(array $values) : ?array
}
note right of Multilingual::__construct
Constructor.
since: 5.0.2
end note
note right of Multilingual::get
Get the other languages
since: 5.0.2
return: ?array
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---263f0227_3cc2_4a88_9818_edb20081c30c---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,90 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* Compiler Language Multilingual
*
* @since 5.0.2
*/
final class Multilingual
{
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
}
/**
* Get the other languages
*
* @param array $values The lang strings to get
*
* @return array
* @since 5.0.2
*/
public function get(array $values): ?array
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from(
$this->db->quoteName(
'#__componentbuilder_language_translation', 'a'
)
);
if (ArrayHelper::check($values))
{
$query->select(
$this->db->quoteName(
array('a.id', 'a.translation', 'a.source', 'a.components',
'a.modules', 'a.plugins', 'a.published')
)
);
$query->where(
$this->db->quoteName('a.source') . ' IN (' . implode(
',', array_map(
fn($a) => $this->db->quote($a), $values
)
) . ')'
);
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
return $this->db->loadAssocList('source');
}
}
return null;
}
}

View File

@ -0,0 +1,63 @@
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
}
/**
* Get the other languages
*
* @param array $values The lang strings to get
*
* @return array
* @since 5.0.2
*/
public function get(array $values): ?array
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from(
$this->db->quoteName(
'#__[[[component]]]_language_translation', 'a'
)
);
if (ArrayHelper::check($values))
{
$query->select(
$this->db->quoteName(
array('a.id', 'a.translation', 'a.source', 'a.components',
'a.modules', 'a.plugins', 'a.published')
)
);
$query->where(
$this->db->quoteName('a.source') . ' IN (' . implode(
',', array_map(
fn($a) => $this->db->quote($a), $values
)
) . ')'
);
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
return $this->db->loadAssocList('source');
}
}
return null;
}

View File

@ -0,0 +1,24 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "263f0227-3cc2-4a88-9818-edb20081c30c",
"implements": null,
"load_selection": null,
"name": "Multilingual",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Language.Multilingual",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Language.Multilingual",
"description": "Compiler Language Multilingual\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;",
"composer": ""
}

View File

@ -0,0 +1,94 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Extension (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin**
```uml
@startuml
class Extension << (F,LightGreen) >> #RoyalBlue {
# Placeholder $placeholder
# Builder $builder
# Parser $parser
+ __construct(Placeholder $placeholder, Builder $builder, ...)
+ get(object $plugin) : string
# addNeededMethods(string $code) : bool
# addGetSubscribedEvents(array $methods) : ?string
# getSubscribedEvents(array $methods) : bool
}
note right of Extension::__construct
Constructor.
since: 5.0.2
arguments:
Placeholder $placeholder
Builder $builder
Parser $parser
end note
note right of Extension::get
Get the updated placeholder content for the given plugin.
since: 5.0.2
return: string
end note
note right of Extension::addNeededMethods
Ensures that the required methods are present in the plugin code.
This method checks the plugin's code for the presence of required methods,
particularly the method that indicates implementation of the SubscriberInterface.
If the necessary method is missing, it adds it to the code.
since: 5.0.2
return: bool
end note
note right of Extension::addGetSubscribedEvents
Add the getSubscribedEvents method
since: 5.0.2
return: ?string
end note
note right of Extension::getSubscribedEvents
Check if the getSubscribedEvents is set
since: 5.0.2
return: bool
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---28c8eed4_58cf_4d40_9053_ad77b6edfa9d---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,215 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Power\Parser;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface;
/**
* Plugin Extension Class for Joomla 5
*
* @since 5.0.2
*/
final class Extension implements ExtensionInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* The Parser Class.
*
* @var Parser
* @since 5.0.2
*/
protected Parser $parser;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
* @param Parser $parser The Parser Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder, Parser $parser)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
$this->parser = $parser;
}
/**
* Get the updated placeholder content for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The updated placeholder content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$add_subscriber_interface = $this->addNeededMethods($plugin->main_class_code);
$extension = [];
$extension[] = $plugin->comment . PHP_EOL . 'final class ';
$extension[] = $plugin->class_name . ' extends ' . $plugin->extends;
if ($add_subscriber_interface)
{
$extension[] = ' implements Joomla__' . '_c06c5116_6b9d_487c_9b09_5094ec4506a3___Power';
}
$extension[] = PHP_EOL . '{' . PHP_EOL;
$extension[] = $plugin->main_class_code;
$extension[] = PHP_EOL . '}' . PHP_EOL;
return $this->placeholder->update(
implode('', $extension),
$this->builder->allActive()
);
}
/**
* Ensures that the required methods are present in the plugin code.
*
* This method checks the plugin's code for the presence of required methods,
* particularly the method that indicates implementation of the SubscriberInterface.
* If the necessary method is missing, it adds it to the code.
*
* @param string $code The main code of the plugin, passed by reference.
*
* @return bool Returns true if the SubscriberInterface implementation is added or already present, false otherwise.
*
* @since 5.0.2
*/
protected function addNeededMethods(string &$code): bool
{
// Parse the code to extract its structure, particularly its methods.
$code_structure = $this->parser->code($code);
if (empty($code_structure['methods']))
{
return false;
}
// Check if methods are defined and if getSubscribedEvents is not present.
if (!$this->getSubscribedEvents($code_structure['methods']))
{
// Attempt to add the getSubscribedEvents method.
$method = $this->addGetSubscribedEvents($code_structure['methods']);
if ($method !== null)
{
// Append the new method to the code and indicate that the interface must be added.
$code .= $method;
return true;
}
// Return false if the event method could not be added.
return false;
}
// Return true if getSubscribedEvents is already present.
return true;
}
/**
* Add the getSubscribedEvents method
*
* @param array $methods The plugin methods.
*
* @return string|null The getSubscribedEvents code
*
* @since 5.0.2
*/
protected function addGetSubscribedEvents(array $methods): ?string
{
$events = [];
$counter = 0;
foreach ($methods as $method)
{
if ($method['access'] === 'public' && !$method['static'] && !$method['abstract'])
{
$events[$method['name']] = Indent::_(3) . "'{$method['name']}' => '{$method['name']}'";
// autoloaded when method start with 'on'
// so we can ignore adding the getSubscribedEvents
if (substr($method['name'], 0, 2) === 'on')
{
$counter++;
}
}
}
if ($events === [] || $counter == count($events))
{
return null;
}
$method = [];
$method[] = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$method[] = Indent::_(1) . ' * Returns an array of events this subscriber will listen to.';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @return array';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @since 5.0.0';
$method[] = Indent::_(1) . ' */';
$method[] = Indent::_(1) . 'public static function getSubscribedEvents(): array';
$method[] = Indent::_(1) . '{';
$method[] = Indent::_(2) . 'return [';
$method[] = implode(',' . PHP_EOL, $events);
$method[] = Indent::_(2) . '];';
$method[] = Indent::_(1) . '}';
return implode(PHP_EOL, $method);
}
/**
* Check if the getSubscribedEvents is set
*
* @param array $methods The plugin methods.
*
* @return bool
*
* @since 5.0.2
*/
protected function getSubscribedEvents(array $methods): bool
{
foreach ($methods as $method)
{
if ($method['name'] === 'getSubscribedEvents' && $method['static'] && !$method['abstract'])
{
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,185 @@
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* The Parser Class.
*
* @var Parser
* @since 5.0.2
*/
protected Parser $parser;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
* @param Parser $parser The Parser Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder, Parser $parser)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
$this->parser = $parser;
}
/**
* Get the updated placeholder content for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The updated placeholder content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$add_subscriber_interface = $this->addNeededMethods($plugin->main_class_code);
$extension = [];
$extension[] = $plugin->comment . PHP_EOL . 'final class ';
$extension[] = $plugin->class_name . ' extends ' . $plugin->extends;
if ($add_subscriber_interface)
{
$extension[] = ' implements Joomla__' . '_c06c5116_6b9d_487c_9b09_5094ec4506a3___Power';
}
$extension[] = PHP_EOL . '{' . PHP_EOL;
$extension[] = $plugin->main_class_code;
$extension[] = PHP_EOL . '}' . PHP_EOL;
return $this->placeholder->update(
implode('', $extension),
$this->builder->allActive()
);
}
/**
* Ensures that the required methods are present in the plugin code.
*
* This method checks the plugin's code for the presence of required methods,
* particularly the method that indicates implementation of the SubscriberInterface.
* If the necessary method is missing, it adds it to the code.
*
* @param string $code The main code of the plugin, passed by reference.
*
* @return bool Returns true if the SubscriberInterface implementation is added or already present, false otherwise.
*
* @since 5.0.2
*/
protected function addNeededMethods(string &$code): bool
{
// Parse the code to extract its structure, particularly its methods.
$code_structure = $this->parser->code($code);
if (empty($code_structure['methods']))
{
return false;
}
// Check if methods are defined and if getSubscribedEvents is not present.
if (!$this->getSubscribedEvents($code_structure['methods']))
{
// Attempt to add the getSubscribedEvents method.
$method = $this->addGetSubscribedEvents($code_structure['methods']);
if ($method !== null)
{
// Append the new method to the code and indicate that the interface must be added.
$code .= $method;
return true;
}
// Return false if the event method could not be added.
return false;
}
// Return true if getSubscribedEvents is already present.
return true;
}
/**
* Add the getSubscribedEvents method
*
* @param array $methods The plugin methods.
*
* @return string|null The getSubscribedEvents code
*
* @since 5.0.2
*/
protected function addGetSubscribedEvents(array $methods): ?string
{
$events = [];
$counter = 0;
foreach ($methods as $method)
{
if ($method['access'] === 'public' && !$method['static'] && !$method['abstract'])
{
$events[$method['name']] = Indent::_(3) . "'{$method['name']}' => '{$method['name']}'";
// autoloaded when method start with 'on'
// so we can ignore adding the getSubscribedEvents
if (substr($method['name'], 0, 2) === 'on')
{
$counter++;
}
}
}
if ($events === [] || $counter == count($events))
{
return null;
}
$method = [];
$method[] = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$method[] = Indent::_(1) . ' * Returns an array of events this subscriber will listen to.';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @return array';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @since 5.0.0';
$method[] = Indent::_(1) . ' */';
$method[] = Indent::_(1) . 'public static function getSubscribedEvents(): array';
$method[] = Indent::_(1) . '{';
$method[] = Indent::_(2) . 'return [';
$method[] = implode(',' . PHP_EOL, $events);
$method[] = Indent::_(2) . '];';
$method[] = Indent::_(1) . '}';
return implode(PHP_EOL, $method);
}
/**
* Check if the getSubscribedEvents is set
*
* @param array $methods The plugin methods.
*
* @return bool
*
* @since 5.0.2
*/
protected function getSubscribedEvents(array $methods): bool
{
foreach ($methods as $method)
{
if ($method['name'] === 'getSubscribedEvents' && $method['static'] && !$method['abstract'])
{
return true;
}
}
return false;
}

View File

@ -0,0 +1,38 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "28c8eed4-58cf-4d40-9053-ad77b6edfa9d",
"implements": [
"914db7f5-82d8-4d3b-a1c1-eb476b1898c2"
],
"load_selection": null,
"name": "Extension",
"power_version": "1.0.0",
"system_name": "JCB.Architecture.J5.Plugin.Extension",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection1": {
"use": "adfbe68a-6d22-43e5-aee8-2787e8c47e75",
"as": "Builder"
},
"use_selection2": {
"use": "95d0e03f-24fd-4412-bc2e-f0899fcc3205",
"as": "default"
},
"use_selection3": {
"use": "a68c010b-e92e-47d5-8a44-d23cfddeb6c6",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Architecture.JoomlaFive.Plugin.Extension",
"description": "Plugin Extension Class for Joomla 5\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -30,6 +30,7 @@ class BuilderLZ #Gold {
+ getModelMediumField(Container $container) : ModelMediumField
+ getModelWhmcsField(Container $container) : ModelWhmcsField
+ getMovedPublishingFields(Container $container) : MovedPublishingFields
+ getMultilingual(Container $container) : Multilingual
+ getMysqlTableSetting(Container $container) : MysqlTableSetting
+ getNewPublishingFields(Container $container) : NewPublishingFields
+ getOrderZero(Container $container) : OrderZero
@ -195,259 +196,266 @@ note left of BuilderLZ::getMovedPublishingFields
return: MovedPublishingFields
end note
note right of BuilderLZ::getMysqlTableSetting
note right of BuilderLZ::getMultilingual
Get The Multilingual Class.
since: 3.2.0
return: Multilingual
end note
note left of BuilderLZ::getMysqlTableSetting
Get The MysqlTableSetting Class.
since: 3.2.0
return: MysqlTableSetting
end note
note left of BuilderLZ::getNewPublishingFields
note right of BuilderLZ::getNewPublishingFields
Get The NewPublishingFields Class.
since: 3.2.0
return: NewPublishingFields
end note
note right of BuilderLZ::getOrderZero
note left of BuilderLZ::getOrderZero
Get The OrderZero Class.
since: 3.2.0
return: OrderZero
end note
note left of BuilderLZ::getOtherFilter
note right of BuilderLZ::getOtherFilter
Get The OtherFilter Class.
since: 3.2.0
return: OtherFilter
end note
note right of BuilderLZ::getOtherGroup
note left of BuilderLZ::getOtherGroup
Get The OtherGroup Class.
since: 3.2.0
return: OtherGroup
end note
note left of BuilderLZ::getOtherJoin
note right of BuilderLZ::getOtherJoin
Get The OtherJoin Class.
since: 3.2.0
return: OtherJoin
end note
note right of BuilderLZ::getOtherOrder
note left of BuilderLZ::getOtherOrder
Get The OtherOrder Class.
since: 3.2.0
return: OtherOrder
end note
note left of BuilderLZ::getOtherQuery
note right of BuilderLZ::getOtherQuery
Get The OtherQuery Class.
since: 3.2.0
return: OtherQuery
end note
note right of BuilderLZ::getOtherWhere
note left of BuilderLZ::getOtherWhere
Get The OtherWhere Class.
since: 3.2.0
return: OtherWhere
end note
note left of BuilderLZ::getPermissionAction
note right of BuilderLZ::getPermissionAction
Get The PermissionAction Class.
since: 3.2.0
return: PermissionAction
end note
note right of BuilderLZ::getPermissionComponent
note left of BuilderLZ::getPermissionComponent
Get The PermissionComponent Class.
since: 3.2.0
return: PermissionComponent
end note
note left of BuilderLZ::getPermissionCore
note right of BuilderLZ::getPermissionCore
Get The PermissionCore Class.
since: 3.2.0
return: PermissionCore
end note
note right of BuilderLZ::getPermissionDashboard
note left of BuilderLZ::getPermissionDashboard
Get The PermissionDashboard Class.
since: 3.2.0
return: PermissionDashboard
end note
note left of BuilderLZ::getPermissionFields
note right of BuilderLZ::getPermissionFields
Get The PermissionFields Class.
since: 3.2.0
return: PermissionFields
end note
note right of BuilderLZ::getPermissionGlobalAction
note left of BuilderLZ::getPermissionGlobalAction
Get The PermissionGlobalAction Class.
since: 3.2.0
return: PermissionGlobalAction
end note
note left of BuilderLZ::getPermissionViews
note right of BuilderLZ::getPermissionViews
Get The PermissionViews Class.
since: 3.2.0
return: PermissionViews
end note
note right of BuilderLZ::getRequest
note left of BuilderLZ::getRequest
Get The Request Class.
since: 3.2.0
return: Request
end note
note left of BuilderLZ::getRouter
note right of BuilderLZ::getRouter
Get The Router Class.
since: 3.2.0
return: Router
end note
note right of BuilderLZ::getScriptMediaSwitch
note left of BuilderLZ::getScriptMediaSwitch
Get The ScriptMediaSwitch Class.
since: 3.2.0
return: ScriptMediaSwitch
end note
note left of BuilderLZ::getScriptUserSwitch
note right of BuilderLZ::getScriptUserSwitch
Get The ScriptUserSwitch Class.
since: 3.2.0
return: ScriptUserSwitch
end note
note right of BuilderLZ::getSearch
note left of BuilderLZ::getSearch
Get The Search Class.
since: 3.2.0
return: Search
end note
note left of BuilderLZ::getSelectionTranslation
note right of BuilderLZ::getSelectionTranslation
Get The SelectionTranslation Class.
since: 3.2.0
return: SelectionTranslation
end note
note right of BuilderLZ::getSiteDecrypt
note left of BuilderLZ::getSiteDecrypt
Get The SiteDecrypt Class.
since: 3.2.0
return: SiteDecrypt
end note
note left of BuilderLZ::getSiteDynamicGet
note right of BuilderLZ::getSiteDynamicGet
Get The SiteDynamicGet Class.
since: 3.2.0
return: SiteDynamicGet
end note
note right of BuilderLZ::getSiteEditView
note left of BuilderLZ::getSiteEditView
Get The SiteEditView Class.
since: 3.2.0
return: SiteEditView
end note
note left of BuilderLZ::getSiteFieldData
note right of BuilderLZ::getSiteFieldData
Get The SiteFieldData Class.
since: 3.2.0
return: SiteFieldData
end note
note right of BuilderLZ::getSiteFieldDecodeFilter
note left of BuilderLZ::getSiteFieldDecodeFilter
Get The SiteFieldDecodeFilter Class.
since: 3.2.0
return: SiteFieldDecodeFilter
end note
note left of BuilderLZ::getSiteFields
note right of BuilderLZ::getSiteFields
Get The SiteFields Class.
since: 3.2.0
return: SiteFields
end note
note right of BuilderLZ::getSiteMainGet
note left of BuilderLZ::getSiteMainGet
Get The SiteMainGet Class.
since: 3.2.0
return: SiteMainGet
end note
note left of BuilderLZ::getSort
note right of BuilderLZ::getSort
Get The Sort Class.
since: 3.2.0
return: Sort
end note
note right of BuilderLZ::getTabCounter
note left of BuilderLZ::getTabCounter
Get The TabCounter Class.
since: 3.2.0
return: TabCounter
end note
note left of BuilderLZ::getTags
note right of BuilderLZ::getTags
Get The Tags Class.
since: 3.2.0
return: Tags
end note
note right of BuilderLZ::getTemplateData
note left of BuilderLZ::getTemplateData
Get The TemplateData Class.
since: 3.2.0
return: TemplateData
end note
note left of BuilderLZ::getTitle
note right of BuilderLZ::getTitle
Get The Title Class.
since: 3.2.0
return: Title
end note
note right of BuilderLZ::getUikitComp
note left of BuilderLZ::getUikitComp
Get The UikitComp Class.
since: 3.2.0
return: UikitComp
end note
note left of BuilderLZ::getUpdateMysql
note right of BuilderLZ::getUpdateMysql
Get The UpdateMysql Class.
since: 3.2.0
return: UpdateMysql
end note
note right of BuilderLZ::getViewsDefaultOrdering
note left of BuilderLZ::getViewsDefaultOrdering
Get The ViewsDefaultOrdering Class.
since: 3.2.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -80,6 +80,10 @@
"use": "9cdff2af-bd1b-452f-810e-d034b9720d2a",
"as": "default"
},
"use_selection54": {
"use": "a8c6158a-6fd2-476b-a5ea-c81f1ecd2356",
"as": "default"
},
"use_selection17": {
"use": "9ff6d6cd-afea-4f15-a67b-fd132d386989",
"as": "default"

View File

@ -0,0 +1,69 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Translation (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Language**
```uml
@startuml
class Translation << (F,LightGreen) >> #RoyalBlue {
# Config $config
# Messages $messages
+ __construct(Config $config, Messages $messages)
+ check(string $tag, array $languageStrings, ...) : bool
}
note right of Translation::__construct
Constructor.
since: 5.0.2
end note
note right of Translation::check
Check if a translation should be added.
This method determines if a translation should be included based on the percentage
of translated strings and logs the decision.
since: 5.0.2
return: bool
arguments:
string $tag
array $languageStrings
int $total
string $file_name
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---344d36be_3949_4848_8cb0_e3d3d9d05c36---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,101 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Builder\LanguageMessages as Messages;
/**
* Compiler Language Translation Checker
*
* @since 5.0.2
*/
final class Translation
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Messages Class.
*
* @var Messages
* @since 5.0.2
*/
protected Messages $messages;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Messages $messages The Language Messages Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Messages $messages)
{
$this->config = $config;
$this->messages = $messages;
}
/**
* Check if a translation should be added.
*
* This method determines if a translation should be included based on the percentage
* of translated strings and logs the decision.
*
* @param string $tag The language tag.
* @param array $languageStrings The active language strings.
* @param int $total The total number of strings.
* @param string $file_name The file name.
*
* @return bool Returns true if the translation should be added; false otherwise.
* @since 5.0.2
*/
public function check(string &$tag, array &$languageStrings, int &$total, string &$file_name): bool
{
$langTag = $this->config->get('lang_tag', 'en-GB');
if ($langTag !== $tag)
{
$langStringNr = count($languageStrings);
$percentage = ($langStringNr / $total) * 100;
$stringName = ($langStringNr == 1) ? "(string $tag translated)" : "(strings $tag translated)";
if (!$this->config->get('debug_line_nr', false))
{
if ($percentage < $this->config->percentage_language_add)
{
$this->messages->set(
"exclude.$file_name",
"<b>$total</b>(total " . $langTag . " strings) only <b>$langStringNr</b> $stringName = $percentage"
);
return false;
}
}
$this->messages->set(
"include.$file_name",
"<b>$total</b>(total " . $langTag . " strings) and <b>$langStringNr</b> $stringName = $percentage"
);
}
return true;
}
}

View File

@ -0,0 +1,74 @@
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Messages Class.
*
* @var Messages
* @since 5.0.2
*/
protected Messages $messages;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Messages $messages The Language Messages Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Messages $messages)
{
$this->config = $config;
$this->messages = $messages;
}
/**
* Check if a translation should be added.
*
* This method determines if a translation should be included based on the percentage
* of translated strings and logs the decision.
*
* @param string $tag The language tag.
* @param array $languageStrings The active language strings.
* @param int $total The total number of strings.
* @param string $file_name The file name.
*
* @return bool Returns true if the translation should be added; false otherwise.
* @since 5.0.2
*/
public function check(string &$tag, array &$languageStrings, int &$total, string &$file_name): bool
{
$langTag = $this->config->get('lang_tag', 'en-GB');
if ($langTag !== $tag)
{
$langStringNr = count($languageStrings);
$percentage = ($langStringNr / $total) * 100;
$stringName = ($langStringNr == 1) ? "(string $tag translated)" : "(strings $tag translated)";
if (!$this->config->get('debug_line_nr', false))
{
if ($percentage < $this->config->percentage_language_add)
{
$this->messages->set(
"exclude.$file_name",
"<b>$total</b>(total " . $langTag . " strings) only <b>$langStringNr</b> $stringName = $percentage"
);
return false;
}
}
$this->messages->set(
"include.$file_name",
"<b>$total</b>(total " . $langTag . " strings) and <b>$langStringNr</b> $stringName = $percentage"
);
}
return true;
}

View File

@ -0,0 +1,28 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "344d36be-3949-4848-8cb0-e3d3d9d05c36",
"implements": null,
"load_selection": null,
"name": "Translation",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Language.Translation",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",
"as": "default"
},
"use_selection1": {
"use": "44efa649-736d-4656-a0ec-e4f1653a6742",
"as": "Messages"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Language.Translation",
"description": "Compiler Language Translation Checker\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -0,0 +1,181 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# class Structure (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour**
```uml
@startuml
class Structure #Gold {
# Plugin $plugin
# Component $component
# Config $config
# Registry $registry
# Dispenser $dispenser
# Event $event
# Counter $counter
# Folder $folder
# File $file
# Files $files
# Placeholder $placeholder
# string $NamespacePrefix
# string $ComponentNamespace
+ __construct(Plugin $plugin, Component $component, ...)
+ build() : void
# getXML(object $plugin) : string
# pluginPath(object $plugin) : void
# setMainClassFile(object $plugin) : void
# setServiceProviderClassFile(object $plugin) : void
# setMainXmlFile(object $plugin) : void
# setInstallScript(object $plugin) : void
# setReadme(object $plugin) : void
# setForms(object $plugin) : void
# setSQL(object $plugin) : void
# setFiles(object $plugin) : void
# setFolders(object $plugin) : void
# setUrls(object $plugin) : void
}
note right of Structure::__construct
Constructor.
since: 3.2.0
arguments:
Plugin $plugin
Component $component
Config $config
Registry $registry
Dispenser $dispenser
Event $event
Counter $counter
Folder $folder
File $file
Files $files
Placeholder $placeholder
end note
note left of Structure::build
Build the Plugins files, folders, url's and config
since: 3.2.0
return: void
end note
note right of Structure::getXML
get the plugin xml template
since: 3.2.0
return: string
end note
note left of Structure::pluginPath
set the plugin path
since: 3.2.0
return: void
end note
note right of Structure::setMainClassFile
set the main class path
since: 3.2.0
return: void
end note
note left of Structure::setServiceProviderClassFile
set the service provider path
since: 3.2.0
return: void
end note
note right of Structure::setMainXmlFile
set the main xml file
since: 3.2.0
return: void
end note
note left of Structure::setInstallScript
set the install script file
since: 3.2.0
return: void
end note
note right of Structure::setReadme
set the readme file
since: 3.2.0
return: void
end note
note left of Structure::setForms
set the form files and folders
since: 3.2.0
return: void
end note
note right of Structure::setSQL
set the sql stuff
since: 3.2.0
return: void
end note
note left of Structure::setFiles
set the files
since: 3.2.0
return: void
end note
note right of Structure::setFolders
set the folders
since: 3.2.0
return: void
end note
note left of Structure::setUrls
set the urls
since: 3.2.0
return: void
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---34daa4c8_45c3_4249_baa3_1bedf8ed3ebc---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,830 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\StructureInterface;
/**
* Joomla 4 Plugin Builder Class
*
* @since 5.0.2
*/
class Structure implements StructureInterface
{
/**
* The Data Class.
*
* @var Plugin
* @since 3.2.0
*/
protected Plugin $plugin;
/**
* The Component Class.
*
* @var Component
* @since 3.2.0
*/
protected Component $component;
/**
* The Config Class.
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* The Registry Class.
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* The Dispenser Class.
*
* @var Dispenser
* @since 3.2.0
*/
protected Dispenser $dispenser;
/**
* The EventInterface Class.
*
* @var Event
* @since 3.2.0
*/
protected Event $event;
/**
* The Counter Class.
*
* @var Counter
* @since 3.2.0
*/
protected Counter $counter;
/**
* The Folder Class.
*
* @var Folder
* @since 3.2.0
*/
protected Folder $folder;
/**
* The File Class.
*
* @var File
* @since 3.2.0
*/
protected File $file;
/**
* The Files Class.
*
* @var Files
* @since 3.2.0
*/
protected Files $files;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.0
*/
protected Placeholder $placeholder;
/**
* The Namespace Prefix
*
* @var string
* @since 5.0.0
*/
protected string $NamespacePrefix;
/**
* The Component Namespace (in code)
*
* @var string
* @since 3.2.0
*/
protected string $ComponentNamespace;
/**
* Constructor.
*
* @param Plugin $plugin The Data Class.
* @param Component $component The Component Class.
* @param Config $config The Config Class.
* @param Registry $registry The Registry Class.
* @param Dispenser $dispenser The Dispenser Class.
* @param Event $event The EventInterface Class.
* @param Counter $counter The Counter Class.
* @param Folder $folder The Folder Class.
* @param File $file The File Class.
* @param Files $files The Files Class.
* @param Placeholder $placeholder The Placeholder Class.
*
* @since 3.2.0
*/
public function __construct(Plugin $plugin, Component $component, Config $config,
Registry $registry, Dispenser $dispenser, Event $event,
Counter $counter, Folder $folder, File $file,
Files $files, Placeholder $placeholder)
{
$this->plugin = $plugin;
$this->component = $component;
$this->config = $config;
$this->registry = $registry;
$this->dispenser = $dispenser;
$this->event = $event;
$this->counter = $counter;
$this->folder = $folder;
$this->file = $file;
$this->files = $files;
$this->placeholder = $placeholder;
// set some global values
$this->NamespacePrefix = $this->placeholder->get('NamespacePrefix');
$this->ComponentNamespace = $this->placeholder->get('ComponentNamespace');
}
/**
* Build the Plugins files, folders, url's and config
*
* @return void
* @since 3.2.0
*/
public function build()
{
if ($this->plugin->exists())
{
// for plugin event TODO change event api signatures
$component_context = $this->config->component_context;
$plugins = $this->plugin->get();
// Trigger Event: jcb_ce_onBeforeSetPlugins
$this->event->trigger(
'jcb_ce_onBeforeBuildPlugins',
array(&$component_context, &$plugins)
);
foreach ($plugins as $plugin)
{
if (ObjectHelper::check($plugin)
&& isset($plugin->folder_name)
&& StringHelper::check($plugin->folder_name))
{
// plugin path
$this->pluginPath($plugin);
// create src folder
$this->folder->create($plugin->folder_path . '/src');
// set the plugin paths
$this->registry->set('dynamic_paths.' . $plugin->key, $plugin->folder_path);
// make sure there is no old build
$this->folder->remove($plugin->folder_path);
// creat the main component folder
$this->folder->create($plugin->folder_path);
// set main class file
$this->setMainClassFile($plugin);
// set service provider class file
$this->setServiceProviderClassFile($plugin);
// set main xml file
$this->setMainXmlFile($plugin);
// set install script if needed
$this->setInstallScript($plugin);
// set readme if found
$this->setReadme($plugin);
// set fields & rules folders if needed
if (isset($plugin->fields_rules_paths)
&& $plugin->fields_rules_paths == 2)
{
// create fields folder
$this->folder->create($plugin->folder_path . '/src/Field');
// create rules folder
$this->folder->create($plugin->folder_path . '/src/Rule');
}
// set forms folder if needed
$this->setForms($plugin);
// set SQL stuff if needed
$this->setSQL($plugin);
// create the language folder path
$this->folder->create($plugin->folder_path . '/language');
// also create the lang tag folder path
$this->folder->create(
$plugin->folder_path . '/language/' . $this->config->get('lang_tag', 'en-GB')
);
// check if this plugin has files
$this->setFiles($plugin);
// check if this plugin has folders
$this->setFolders($plugin);
// check if this plugin has urls
$this->setUrls($plugin);
}
}
}
}
/**
* get the plugin xml template
*
* @param object $plugin The plugin object
*
* @return string
* @since 3.2.0
*/
protected function getXML(object $plugin): string
{
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<extension type="plugin" version="'
. $this->config->joomla_versions[$this->config->joomla_version]['xml_version'] . '" group="'
. $plugin->group . '" method="upgrade">';
$xml .= PHP_EOL . Indent::_(1) . '<name>' . $plugin->lang_prefix
. '</name>';
$xml .= PHP_EOL . Indent::_(1) . '<creationDate>' . Placefix::_h('BUILDDATE') . '</creationDate>';
$xml .= PHP_EOL . Indent::_(1) . '<author>' . Placefix::_h('AUTHOR') . '</author>';
$xml .= PHP_EOL . Indent::_(1) . '<authorEmail>' . Placefix::_h('AUTHOREMAIL') . '</authorEmail>';
$xml .= PHP_EOL . Indent::_(1) . '<authorUrl>' . Placefix::_h('AUTHORWEBSITE') . '</authorUrl>';
$xml .= PHP_EOL . Indent::_(1) . '<copyright>' . Placefix::_h('COPYRIGHT') . '</copyright>';
$xml .= PHP_EOL . Indent::_(1) . '<license>' . Placefix::_h('LICENSE') . '</license>';
$xml .= PHP_EOL . Indent::_(1) . '<version>' . $plugin->plugin_version
. '</version>';
$xml .= PHP_EOL . Indent::_(1) . '<namespace path="src">' . "{$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}"
. '</namespace>';
$xml .= PHP_EOL . Indent::_(1) . '<description>' . $plugin->lang_prefix
. '_XML_DESCRIPTION</description>';
$xml .= Placefix::_h('MAINXML');
$xml .= PHP_EOL . '</extension>';
return $xml;
}
/**
* set the plugin path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function pluginPath(object &$plugin): void
{
$plugin->folder_path = $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/'
. $plugin->folder_name;
}
/**
* set the main class path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainClassFile(object $plugin): void
{
// create extension folder
$this->folder->create($plugin->folder_path . '/src/Extension');
$file_details = [
'path' => $plugin->folder_path . '/src/Extension/' . $plugin->class_file_name . '.php',
'name' => $plugin->class_file_name . '.php',
'zip' => 'src/Extension/' . $plugin->class_file_name . '.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin main class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
"namespace {$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}\\Extension;" .
PHP_EOL . PHP_EOL . Placefix::_h('EXTENSION_CLASS_HEADER') .
PHP_EOL . PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('EXTENSION_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the service provider path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setServiceProviderClassFile(object $plugin): void
{
// create services folder
$this->folder->create($plugin->folder_path . '/services');
$file_details = [
'path' => $plugin->folder_path . '/services/provider.php',
'name' => 'provider.php',
'zip' => 'services/provider.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin services provider class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('PROVIDER_CLASS_HEADER') .
Placefix::_h('PROVIDER_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the main xml file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainXmlFile(object $plugin): void
{
$file_details = [
'path' => $plugin->folder_path . '/' . $plugin->file_name . '.xml',
'name' => $plugin->file_name . '.xml',
'zip' => $plugin->file_name . '.xml'
];
$this->file->write(
$file_details['path'],
$this->getXML($plugin)
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the install script file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setInstallScript(object $plugin): void
{
if ($plugin->add_install_script)
{
$file_details = [
'path' => $plugin->folder_path . '/script.php',
'name' => 'script.php',
'zip' => 'script.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
Placefix::_h('INSTALL_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the readme file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setReadme(object $plugin): void
{
if ($plugin->addreadme)
{
$file_details = [
'path' => $plugin->folder_path . '/README.md',
'name' => 'README.md',
'zip' => 'README.md'
];
$this->file->write($file_details['path'], $plugin->readme);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the form files and folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setForms(object $plugin): void
{
if (isset($plugin->form_files)
&& ArrayHelper::check($plugin->form_files))
{
$Group = ucfirst((string) $plugin->group);
$FileName = $plugin->file_name;
// create forms folder
$this->folder->create($plugin->folder_path . '/forms');
// set the template files
foreach ($plugin->form_files as $file => $fields)
{
// set file details
$file_details = [
'path' => $plugin->folder_path . '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file . '.xml'
];
// build basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<!--' . Line::_(__Line__, __Class__)
. ' default paths of ' . $file
. ' form points to ' . $this->config->component_code_name
. ' -->';
// search if we must add the component path
$add_component_path = false;
foreach ($fields as $field_name => $fieldsets)
{
if (!$add_component_path)
{
foreach ($fieldsets as $fieldset => $field)
{
if (!$add_component_path
&& isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& $plugin->fieldsets_paths[$file. $field_name . $fieldset] == 1)
{
$add_component_path = true;
}
}
}
}
// only add if part of the component field types path is required
if ($add_component_path)
{
$xml .= PHP_EOL . '<form';
$xml .= PHP_EOL . Indent::_(1)
. 'addruleprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Rule"';
$xml .= PHP_EOL . Indent::_(1)
.'addfieldprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Field"';
$xml .= PHP_EOL . '>';
}
else
{
$xml .= PHP_EOL . '<form>';
}
// add the fields
foreach ($fields as $field_name => $fieldsets)
{
// check if we have an double fields naming set
$field_name_inner = '';
$field_name_outer = $field_name;
if (strpos((string)$field_name, '.') !== false)
{
$field_names = explode('.', (string)$field_name);
if (count((array)$field_names) == 2)
{
$field_name_outer = $field_names[0];
$field_name_inner = $field_names[1];
}
}
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="' . $field_name_outer
. '">';
foreach ($fieldsets as $fieldset => $field)
{
// default to the field set name
$label = $fieldset;
if (isset($plugin->fieldsets_label[$file . $field_name . $fieldset]))
{
$label = $plugin->fieldsets_label[$file . $field_name . $fieldset];
}
// add path to plugin rules and custom fields
if (isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& ($plugin->fieldsets_paths[$file . $field_name . $fieldset] == 2
|| $plugin->fieldsets_paths[$file . $field_name . $fieldset] == 3))
{
if (!isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$plugin->add_rule_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Rule";
}
if (!isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$plugin->add_field_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Field";
}
}
// add path to plugin rules and custom fields
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset])
|| isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(1) . '<!--'
. Line::_(__Line__, __Class__) . ' default paths of '
. $fieldset . ' fieldset points to the plugin -->';
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '"';
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addrulepath="' . $plugin->add_rule_path[$file . $field_name . $fieldset] . '"';
}
if (isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addfieldpath="' . $plugin->add_field_path[$file . $field_name . $fieldset] . '"';
}
$xml .= PHP_EOL . Indent::_(1) . '>';
}
else
{
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '">';
}
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="'
. $field_name_inner . '">';
}
// add the placeholder of the fields
$xml .= Placefix::_h('FIELDSET_' . $file
. $field_name . $fieldset);
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '</fields>';
}
$xml .= PHP_EOL . Indent::_(1)
. '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . '</form>';
// add xml to file
$this->file->write($file_details['path'], $xml);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the sql stuff
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setSQL(object $plugin): void
{
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
// create SQL folder
$this->folder->create($plugin->folder_path . '/sql');
// create mysql folder
$this->folder->create(
$plugin->folder_path . '/sql/mysql'
);
// now set the install file
if ($plugin->add_sql)
{
$this->file->write(
$plugin->folder_path . '/sql/mysql/install.sql',
$plugin->sql
);
// count the file created
$this->counter->file++;
}
// now set the uninstall file
if ($plugin->add_sql_uninstall)
{
$this->file->write(
$plugin->folder_path
. '/sql/mysql/uninstall.sql',
$plugin->sql_uninstall
);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the files
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFiles(object $plugin): void
{
if (isset($plugin->files) && ArrayHelper::check($plugin->files))
{
// add to component files
foreach ($plugin->files as $file)
{
// set the path finder
$file['target_type'] = $plugin->target_type;
$file['target_id'] = $plugin->id;
$this->component->appendArray('files', $file);
}
}
}
/**
* set the folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFolders(object $plugin): void
{
if (isset($plugin->folders) && ArrayHelper::check($plugin->folders))
{
// add to component folders
foreach ($plugin->folders as $folder)
{
// set the path finder
$folder['target_type'] = $plugin->target_type;
$folder['target_id'] = $plugin->id;
$this->component->appendArray('folders', $folder);
}
}
}
/**
* set the urls
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setUrls(object &$plugin): void
{
if (isset($plugin->urls) && ArrayHelper::check($plugin->urls))
{
// add to component urls
foreach ($plugin->urls as &$url)
{
// should we add the local folder
if (isset($url['type']) && $url['type'] > 1
&& isset($url['url'])
&& StringHelper::check($url['url']))
{
// set file name
$fileName = basename((string)$url['url']);
// get the file contents
$data = FileHelper::getContent(
$url['url']
);
// build sub path
if (strpos($fileName, '.js') !== false)
{
$path = '/js';
}
elseif (strpos($fileName, '.css') !== false)
{
$path = '/css';
}
else
{
$path = '';
}
// create sub media folder path if not set
$this->folder->create(
$plugin->folder_path . $path
);
// set the path to plugin file
$url['path'] = $plugin->folder_path . $path
. '/' . $fileName; // we need this for later
// write data to path
$this->file->write($url['path'], $data);
// count the file created
$this->counter->file++;
}
}
}
}
}

View File

@ -0,0 +1,786 @@
/**
* The Data Class.
*
* @var Plugin
* @since 3.2.0
*/
protected Plugin $plugin;
/**
* The Component Class.
*
* @var Component
* @since 3.2.0
*/
protected Component $component;
/**
* The Config Class.
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* The Registry Class.
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* The Dispenser Class.
*
* @var Dispenser
* @since 3.2.0
*/
protected Dispenser $dispenser;
/**
* The EventInterface Class.
*
* @var Event
* @since 3.2.0
*/
protected Event $event;
/**
* The Counter Class.
*
* @var Counter
* @since 3.2.0
*/
protected Counter $counter;
/**
* The Folder Class.
*
* @var Folder
* @since 3.2.0
*/
protected Folder $folder;
/**
* The File Class.
*
* @var File
* @since 3.2.0
*/
protected File $file;
/**
* The Files Class.
*
* @var Files
* @since 3.2.0
*/
protected Files $files;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.0
*/
protected Placeholder $placeholder;
/**
* The Namespace Prefix
*
* @var string
* @since 5.0.0
*/
protected string $NamespacePrefix;
/**
* The Component Namespace (in code)
*
* @var string
* @since 3.2.0
*/
protected string $ComponentNamespace;
/**
* Constructor.
*
* @param Plugin $plugin The Data Class.
* @param Component $component The Component Class.
* @param Config $config The Config Class.
* @param Registry $registry The Registry Class.
* @param Dispenser $dispenser The Dispenser Class.
* @param Event $event The EventInterface Class.
* @param Counter $counter The Counter Class.
* @param Folder $folder The Folder Class.
* @param File $file The File Class.
* @param Files $files The Files Class.
* @param Placeholder $placeholder The Placeholder Class.
*
* @since 3.2.0
*/
public function __construct(Plugin $plugin, Component $component, Config $config,
Registry $registry, Dispenser $dispenser, Event $event,
Counter $counter, Folder $folder, File $file,
Files $files, Placeholder $placeholder)
{
$this->plugin = $plugin;
$this->component = $component;
$this->config = $config;
$this->registry = $registry;
$this->dispenser = $dispenser;
$this->event = $event;
$this->counter = $counter;
$this->folder = $folder;
$this->file = $file;
$this->files = $files;
$this->placeholder = $placeholder;
// set some global values
$this->NamespacePrefix = $this->placeholder->get('NamespacePrefix');
$this->ComponentNamespace = $this->placeholder->get('ComponentNamespace');
}
/**
* Build the Plugins files, folders, url's and config
*
* @return void
* @since 3.2.0
*/
public function build()
{
if ($this->plugin->exists())
{
// for plugin event TODO change event api signatures
$component_context = $this->config->component_context;
$plugins = $this->plugin->get();
// Trigger Event: jcb_ce_onBeforeSetPlugins
$this->event->trigger(
'jcb_ce_onBeforeBuildPlugins',
array(&$component_context, &$plugins)
);
foreach ($plugins as $plugin)
{
if (ObjectHelper::check($plugin)
&& isset($plugin->folder_name)
&& StringHelper::check($plugin->folder_name))
{
// plugin path
$this->pluginPath($plugin);
// create src folder
$this->folder->create($plugin->folder_path . '/src');
// set the plugin paths
$this->registry->set('dynamic_paths.' . $plugin->key, $plugin->folder_path);
// make sure there is no old build
$this->folder->remove($plugin->folder_path);
// creat the main component folder
$this->folder->create($plugin->folder_path);
// set main class file
$this->setMainClassFile($plugin);
// set service provider class file
$this->setServiceProviderClassFile($plugin);
// set main xml file
$this->setMainXmlFile($plugin);
// set install script if needed
$this->setInstallScript($plugin);
// set readme if found
$this->setReadme($plugin);
// set fields & rules folders if needed
if (isset($plugin->fields_rules_paths)
&& $plugin->fields_rules_paths == 2)
{
// create fields folder
$this->folder->create($plugin->folder_path . '/src/Field');
// create rules folder
$this->folder->create($plugin->folder_path . '/src/Rule');
}
// set forms folder if needed
$this->setForms($plugin);
// set SQL stuff if needed
$this->setSQL($plugin);
// create the language folder path
$this->folder->create($plugin->folder_path . '/language');
// also create the lang tag folder path
$this->folder->create(
$plugin->folder_path . '/language/' . $this->config->get('lang_tag', 'en-GB')
);
// check if this plugin has files
$this->setFiles($plugin);
// check if this plugin has folders
$this->setFolders($plugin);
// check if this plugin has urls
$this->setUrls($plugin);
}
}
}
}
/**
* get the plugin xml template
*
* @param object $plugin The plugin object
*
* @return string
* @since 3.2.0
*/
protected function getXML(object $plugin): string
{
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<extension type="plugin" version="'
. $this->config->joomla_versions[$this->config->joomla_version]['xml_version'] . '" group="'
. $plugin->group . '" method="upgrade">';
$xml .= PHP_EOL . Indent::_(1) . '<name>' . $plugin->lang_prefix
. '</name>';
$xml .= PHP_EOL . Indent::_(1) . '<creationDate>' . Placefix::_h('BUILDDATE') . '</creationDate>';
$xml .= PHP_EOL . Indent::_(1) . '<author>' . Placefix::_h('AUTHOR') . '</author>';
$xml .= PHP_EOL . Indent::_(1) . '<authorEmail>' . Placefix::_h('AUTHOREMAIL') . '</authorEmail>';
$xml .= PHP_EOL . Indent::_(1) . '<authorUrl>' . Placefix::_h('AUTHORWEBSITE') . '</authorUrl>';
$xml .= PHP_EOL . Indent::_(1) . '<copyright>' . Placefix::_h('COPYRIGHT') . '</copyright>';
$xml .= PHP_EOL . Indent::_(1) . '<license>' . Placefix::_h('LICENSE') . '</license>';
$xml .= PHP_EOL . Indent::_(1) . '<version>' . $plugin->plugin_version
. '</version>';
$xml .= PHP_EOL . Indent::_(1) . '<namespace path="src">' . "{$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}"
. '</namespace>';
$xml .= PHP_EOL . Indent::_(1) . '<description>' . $plugin->lang_prefix
. '_XML_DESCRIPTION</description>';
$xml .= Placefix::_h('MAINXML');
$xml .= PHP_EOL . '</extension>';
return $xml;
}
/**
* set the plugin path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function pluginPath(object &$plugin): void
{
$plugin->folder_path = $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/'
. $plugin->folder_name;
}
/**
* set the main class path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainClassFile(object $plugin): void
{
// create extension folder
$this->folder->create($plugin->folder_path . '/src/Extension');
$file_details = [
'path' => $plugin->folder_path . '/src/Extension/' . $plugin->class_file_name . '.php',
'name' => $plugin->class_file_name . '.php',
'zip' => 'src/Extension/' . $plugin->class_file_name . '.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin main class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
"namespace {$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}\\Extension;" .
PHP_EOL . PHP_EOL . Placefix::_h('EXTENSION_CLASS_HEADER') .
PHP_EOL . PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('EXTENSION_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the service provider path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setServiceProviderClassFile(object $plugin): void
{
// create services folder
$this->folder->create($plugin->folder_path . '/services');
$file_details = [
'path' => $plugin->folder_path . '/services/provider.php',
'name' => 'provider.php',
'zip' => 'services/provider.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin services provider class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('PROVIDER_CLASS_HEADER') .
Placefix::_h('PROVIDER_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the main xml file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainXmlFile(object $plugin): void
{
$file_details = [
'path' => $plugin->folder_path . '/' . $plugin->file_name . '.xml',
'name' => $plugin->file_name . '.xml',
'zip' => $plugin->file_name . '.xml'
];
$this->file->write(
$file_details['path'],
$this->getXML($plugin)
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the install script file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setInstallScript(object $plugin): void
{
if ($plugin->add_install_script)
{
$file_details = [
'path' => $plugin->folder_path . '/script.php',
'name' => 'script.php',
'zip' => 'script.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
Placefix::_h('INSTALL_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the readme file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setReadme(object $plugin): void
{
if ($plugin->addreadme)
{
$file_details = [
'path' => $plugin->folder_path . '/README.md',
'name' => 'README.md',
'zip' => 'README.md'
];
$this->file->write($file_details['path'], $plugin->readme);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the form files and folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setForms(object $plugin): void
{
if (isset($plugin->form_files)
&& ArrayHelper::check($plugin->form_files))
{
$Group = ucfirst((string) $plugin->group);
$FileName = $plugin->file_name;
// create forms folder
$this->folder->create($plugin->folder_path . '/forms');
// set the template files
foreach ($plugin->form_files as $file => $fields)
{
// set file details
$file_details = [
'path' => $plugin->folder_path . '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file . '.xml'
];
// build basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<!--' . Line::_(__Line__, __Class__)
. ' default paths of ' . $file
. ' form points to ' . $this->config->component_code_name
. ' -->';
// search if we must add the component path
$add_component_path = false;
foreach ($fields as $field_name => $fieldsets)
{
if (!$add_component_path)
{
foreach ($fieldsets as $fieldset => $field)
{
if (!$add_component_path
&& isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& $plugin->fieldsets_paths[$file. $field_name . $fieldset] == 1)
{
$add_component_path = true;
}
}
}
}
// only add if part of the component field types path is required
if ($add_component_path)
{
$xml .= PHP_EOL . '<form';
$xml .= PHP_EOL . Indent::_(1)
. 'addruleprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Rule"';
$xml .= PHP_EOL . Indent::_(1)
.'addfieldprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Field"';
$xml .= PHP_EOL . '>';
}
else
{
$xml .= PHP_EOL . '<form>';
}
// add the fields
foreach ($fields as $field_name => $fieldsets)
{
// check if we have an double fields naming set
$field_name_inner = '';
$field_name_outer = $field_name;
if (strpos((string)$field_name, '.') !== false)
{
$field_names = explode('.', (string)$field_name);
if (count((array)$field_names) == 2)
{
$field_name_outer = $field_names[0];
$field_name_inner = $field_names[1];
}
}
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="' . $field_name_outer
. '">';
foreach ($fieldsets as $fieldset => $field)
{
// default to the field set name
$label = $fieldset;
if (isset($plugin->fieldsets_label[$file . $field_name . $fieldset]))
{
$label = $plugin->fieldsets_label[$file . $field_name . $fieldset];
}
// add path to plugin rules and custom fields
if (isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& ($plugin->fieldsets_paths[$file . $field_name . $fieldset] == 2
|| $plugin->fieldsets_paths[$file . $field_name . $fieldset] == 3))
{
if (!isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$plugin->add_rule_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Rule";
}
if (!isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$plugin->add_field_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Field";
}
}
// add path to plugin rules and custom fields
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset])
|| isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(1) . '<!--'
. Line::_(__Line__, __Class__) . ' default paths of '
. $fieldset . ' fieldset points to the plugin -->';
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '"';
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addrulepath="' . $plugin->add_rule_path[$file . $field_name . $fieldset] . '"';
}
if (isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addfieldpath="' . $plugin->add_field_path[$file . $field_name . $fieldset] . '"';
}
$xml .= PHP_EOL . Indent::_(1) . '>';
}
else
{
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '">';
}
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="'
. $field_name_inner . '">';
}
// add the placeholder of the fields
$xml .= Placefix::_h('FIELDSET_' . $file
. $field_name . $fieldset);
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '</fields>';
}
$xml .= PHP_EOL . Indent::_(1)
. '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . '</form>';
// add xml to file
$this->file->write($file_details['path'], $xml);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the sql stuff
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setSQL(object $plugin): void
{
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
// create SQL folder
$this->folder->create($plugin->folder_path . '/sql');
// create mysql folder
$this->folder->create(
$plugin->folder_path . '/sql/mysql'
);
// now set the install file
if ($plugin->add_sql)
{
$this->file->write(
$plugin->folder_path . '/sql/mysql/install.sql',
$plugin->sql
);
// count the file created
$this->counter->file++;
}
// now set the uninstall file
if ($plugin->add_sql_uninstall)
{
$this->file->write(
$plugin->folder_path
. '/sql/mysql/uninstall.sql',
$plugin->sql_uninstall
);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the files
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFiles(object $plugin): void
{
if (isset($plugin->files) && ArrayHelper::check($plugin->files))
{
// add to component files
foreach ($plugin->files as $file)
{
// set the path finder
$file['target_type'] = $plugin->target_type;
$file['target_id'] = $plugin->id;
$this->component->appendArray('files', $file);
}
}
}
/**
* set the folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFolders(object $plugin): void
{
if (isset($plugin->folders) && ArrayHelper::check($plugin->folders))
{
// add to component folders
foreach ($plugin->folders as $folder)
{
// set the path finder
$folder['target_type'] = $plugin->target_type;
$folder['target_id'] = $plugin->id;
$this->component->appendArray('folders', $folder);
}
}
}
/**
* set the urls
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setUrls(object &$plugin): void
{
if (isset($plugin->urls) && ArrayHelper::check($plugin->urls))
{
// add to component urls
foreach ($plugin->urls as &$url)
{
// should we add the local folder
if (isset($url['type']) && $url['type'] > 1
&& isset($url['url'])
&& StringHelper::check($url['url']))
{
// set file name
$fileName = basename((string)$url['url']);
// get the file contents
$data = FileHelper::getContent(
$url['url']
);
// build sub path
if (strpos($fileName, '.js') !== false)
{
$path = '/js';
}
elseif (strpos($fileName, '.css') !== false)
{
$path = '/css';
}
else
{
$path = '';
}
// create sub media folder path if not set
$this->folder->create(
$plugin->folder_path . $path
);
// set the path to plugin file
$url['path'] = $plugin->folder_path . $path
. '/' . $fileName; // we need this for later
// write data to path
$this->file->write($url['path'], $data);
// count the file created
$this->counter->file++;
}
}
}
}

View File

@ -0,0 +1,94 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "34daa4c8-45c3-4249-baa3-1bedf8ed3ebc",
"implements": [
"ef66b17c-ffae-414a-9067-20a63ba2bec5"
],
"load_selection": null,
"name": "Structure",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Joomlaplugin.J4.Structure",
"type": "class",
"use_selection": {
"use_selection0": {
"use": "8cc85656-a925-4a46-a49b-83c72167fd6a",
"as": "Plugin"
},
"use_selection1": {
"use": "e2472b22-a329-44d8-b4a2-ae3ba99e17a0",
"as": "default"
},
"use_selection2": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",
"as": "default"
},
"use_selection3": {
"use": "e5d9804f-0eb0-4ee9-b406-ad4e8cdbc1f6",
"as": "default"
},
"use_selection4": {
"use": "f1dc6430-fb54-452e-aa53-ce32ae93db88",
"as": "default"
},
"use_selection5": {
"use": "20ed72b0-fcac-4344-aee1-8a65e3bf221d",
"as": "Event"
},
"use_selection6": {
"use": "e6d871a6-bbe7-497d-af01-68f6bb9a87f4",
"as": "default"
},
"use_selection7": {
"use": "6bbb6ffe-3f09-4c21-aa9d-c93159afa1e1",
"as": "default"
},
"use_selection8": {
"use": "5c75b455-3d4c-452a-867e-e90424a64c88",
"as": "default"
},
"use_selection9": {
"use": "1d967151-7c20-4ca7-9400-65233cdcd4db",
"as": "default"
},
"use_selection10": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection11": {
"use": "a68c010b-e92e-47d5-8a44-d23cfddeb6c6",
"as": "default"
},
"use_selection12": {
"use": "500f3a7f-c16d-4dd4-81b2-2df6776b5388",
"as": "default"
},
"use_selection13": {
"use": "4e6ff11d-bebf-42f5-8fd7-b2f882857222",
"as": "default"
},
"use_selection14": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
},
"use_selection15": {
"use": "91004529-94a9-4590-b842-e7c6b624ecf5",
"as": "default"
},
"use_selection16": {
"use": "1f28cb53-60d9-4db1-b517-3c7dc6b429ef",
"as": "default"
},
"use_selection17": {
"use": "a223b31e-ea1d-4cdf-92ae-5f9becffaff0",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Joomlaplugin.JoomlaFour.Structure",
"description": "Joomla 4 Plugin Builder Class\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -0,0 +1,95 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Data (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour**
```uml
@startuml
class Data << (F,LightGreen) >> #RoyalBlue {
# array $data
# Config $config
# Customcode $customcode
# Gui $gui
# Placeholder $placeholder
# Language $language
# Field $field
# FieldName $fieldname
# Filesfolders $filesfolders
# $db
+ __construct(Config $config, Customcode $customcode, ...)
+ get(int $id = null) : object|array|null
+ exists(int $id = null) : bool
+ set(int $id) : bool
}
note right of Data::__construct
Constructor.
since: 5.0.2
arguments:
Config $config
Customcode $customcode
Gui $gui
Placeholder $placeholder
Language $language
Field $field
FieldName $fieldname
Filesfolders $filesfolders
end note
note right of Data::get
Get the Joomla Plugin/s
since: 3.2.0
return: object|array|null
end note
note right of Data::exists
Check if the Joomla Plugin/s exists
since: 3.2.0
return: bool
end note
note right of Data::set
Set the Joomla Plugin
since: 3.2.0
return: bool
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---361e08c0_5916_4b77_b6a2_c16a769bbc40---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,934 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour;
use Joomla\CMS\Factory;
use Joomla\CMS\Filter\OutputFilter;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Customcode;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Field;
use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName;
use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\String\ClassfunctionHelper;
use VDM\Joomla\Utilities\String\PluginHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\GetHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface;
/**
* Joomla 4 Plug-in Data Class
*
* @since 5.0.2
*/
final class Data implements PluginDataInterface
{
/**
* Compiler Joomla Plug-in's Data
*
* @var array
* @since 3.2.0
*/
protected array $data = [];
/**
* The Configure Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Customcode Class.
*
* @var Customcode
* @since 5.0.2
*/
protected Customcode $customcode;
/**
* The Gui Class.
*
* @var Gui
* @since 5.0.2
*/
protected Gui $gui;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Field Class.
*
* @var Field
* @since 5.0.2
*/
protected Field $field;
/**
* The Name Class.
*
* @var FieldName
* @since 5.0.2
*/
protected FieldName $fieldname;
/**
* The Filesfolders Class.
*
* @var Filesfolders
* @since 5.0.2
*/
protected Filesfolders $filesfolders;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Define the mappings of traits and classes to their respective methods and services
*
* @var array
* @since 5.0.2
**/
protected array $service_checks = [
'DatabaseAwareTrait' => [
'trait' => 'Joomla\Database\DatabaseAwareTrait',
'class' => 'Joomla__'.'_ae15e6b6_f7de_43ad_be4b_71499ae88f45___Power',
'method' => 'setDatabase',
'service' => 'Joomla__'.'_7bd29d76_73c9_4c07_a5da_4f7a32aff78f___Power'
],
'UserFactoryAwareTrait' => [
'trait' => 'Joomla\CMS\User\UserFactoryAwareTrait',
'class' => 'Joomla__'.'_a6b2c321_5de3_4425_b05f_e5340965fb80___Power',
'method' => 'setUserFactory',
'service' => 'Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power'
]
];
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Customcode $customcode The Customcode Class.
* @param Gui $gui The Gui Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Language Class.
* @param Field $field The Field Class.
* @param FieldName $fieldname The Name Class.
* @param Filesfolders $filesfolders The Filesfolders Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Customcode $customcode, Gui $gui,
Placeholder $placeholder, Language $language,
Field $field, FieldName $fieldname,
Filesfolders $filesfolders)
{
$this->config = $config;
$this->customcode = $customcode;
$this->gui = $gui;
$this->placeholder = $placeholder;
$this->language = $language;
$this->field = $field;
$this->fieldname = $fieldname;
$this->filesfolders = $filesfolders;
$this->db = Factory::getDbo();
}
/**
* Get the Joomla Plugin/s
*
* @param int|null $id the plugin id
*
* @return object|array|null if ID found it returns object, if no ID given it returns all set
* @since 3.2.0
*/
public function get(int $id = null)
{
if (is_null($id) && $this->exists())
{
return $this->data;
}
elseif ($this->exists($id))
{
return $this->data[$id];
}
return null;
}
/**
* Check if the Joomla Plugin/s exists
*
* @param int|null $id the plugin id
*
* @return bool if ID found it returns true, if no ID given it returns true if any are set
* @since 3.2.0
*/
public function exists(int $id = null): bool
{
if (is_null($id))
{
return ArrayHelper::check($this->data);
}
elseif (isset($this->data[$id]))
{
return true;
}
return $this->set($id);
}
/**
* Set the Joomla Plugin
*
* @param int $id the plugin id
*
* @return bool true on success
* @since 3.2.0
*/
public function set(int $id): bool
{
if (isset($this->data[$id]))
{
return true;
}
else
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->select('a.*');
$query->select(
$this->db->quoteName(
array(
'g.name',
'e.name',
'e.head',
'e.comment',
'e.id',
'f.addfiles',
'f.addfolders',
'f.addfilesfullpath',
'f.addfoldersfullpath',
'f.addurls',
'u.version_update',
'u.id'
), array(
'group',
'extends',
'class_head',
'comment',
'class_id',
'addfiles',
'addfolders',
'addfilesfullpath',
'addfoldersfullpath',
'addurls',
'version_update',
'version_update_id'
)
)
);
// from these tables
$query->from('#__componentbuilder_joomla_plugin AS a');
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_group', 'g'
) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group')
. ' = ' . $this->db->quoteName('g.id') . ')'
);
$query->join(
'LEFT',
$this->db->quoteName('#__componentbuilder_class_extends', 'e')
. ' ON (' . $this->db->quoteName('a.class_extends') . ' = '
. $this->db->quoteName('e.id') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_updates', 'u'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('u.joomla_plugin') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_files_folders_urls', 'f'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('f.joomla_plugin') . ')'
);
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
$query->where($this->db->quoteName('a.published') . ' >= 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
// get the plugin data
$plugin = $this->db->loadObject();
// tweak system to set stuff to the plugin domain
$_backup_target = $this->config->build_target;
$_backup_lang = $this->config->lang_target;
$_backup_langPrefix = $this->config->lang_prefix;
// set some keys
$plugin->target_type = 'pLuG!n';
$plugin->key = $plugin->id . '_' . $plugin->target_type;
// update to point to plugin
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
// set version if not set
if (empty($plugin->plugin_version))
{
$plugin->plugin_version = '1.0.0';
}
// set GUI mapper
$guiMapper = array('table' => 'joomla_plugin',
'id' => (int) $id, 'type' => 'php');
// update the name if it has dynamic values
$plugin->name = $this->placeholder->update_(
$this->customcode->update($plugin->name)
);
// update the name if it has dynamic values
$plugin->code_name
= ClassfunctionHelper::safe(
$plugin->name
);
// set official name
$plugin->official_name = ucwords(
$plugin->group . ' - ' . $plugin->name
);
// set lang prefix
$plugin->lang_prefix = PluginHelper::safeLangPrefix(
$plugin->code_name,
$plugin->group
);
// set langPrefix
$this->config->lang_prefix = $plugin->lang_prefix;
// set plugin class name
$plugin->class_name = ucfirst(
$plugin->code_name
);
// set plugin context name
$plugin->context_name = strtolower((string)
$plugin->code_name
);
// set plugin namespace
$plugin->namespace = $plugin->code_name;
// set plugin group namespace
$plugin->group_namespace = ucfirst(
$plugin->group
);
// set plugin install class name
$plugin->installer_class_name
= PluginHelper::safeInstallClassName(
$plugin->code_name,
$plugin->group
);
// set plugin folder name
$plugin->folder_name
= PluginHelper::safeFolderName(
$plugin->code_name,
$plugin->group
);
// set the zip name
$plugin->zip_name = $plugin->folder_name . '_v' . str_replace(
'.', '_', (string) $plugin->plugin_version
) . '__J' . $this->config->joomla_version;
// set plugin file name
$plugin->file_name = $plugin->context_name;
$plugin->class_file_name = $plugin->code_name;
// set plugin context
$plugin->context = $plugin->folder_name . '.' . $plugin->id;
// set official_name lang strings
$this->language->set(
$plugin->key, $this->config->lang_prefix, $plugin->official_name
);
// set some placeholder for this plugin
$this->placeholder->set('Plugin_name', $plugin->official_name);
$this->placeholder->set('PLUGIN_NAME', $plugin->official_name);
$this->placeholder->set('Plugin', ucfirst((string) $plugin->code_name));
$this->placeholder->set('plugin', strtolower((string) $plugin->code_name));
$this->placeholder->set('Plugin_group', ucfirst((string) $plugin->group));
$this->placeholder->set('plugin_group', strtolower((string) $plugin->group));
$this->placeholder->set('plugin.version', $plugin->plugin_version);
$this->placeholder->set('VERSION', $plugin->plugin_version);
$this->placeholder->set('plugin_version', str_replace(
'.', '_', (string) $plugin->plugin_version
));
// set description
$this->placeholder->set('DESCRIPTION', '');
if (!isset($plugin->description)
|| !StringHelper::check(
$plugin->description
))
{
$plugin->description = '';
}
else
{
$plugin->description = $this->placeholder->update_(
$this->customcode->update($plugin->description)
);
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_DESCRIPTION',
$plugin->description
);
// set description
$this->placeholder->set('DESCRIPTION', $plugin->description);
$plugin->description = '<p>' . $plugin->description . '</p>';
}
// get author name
$project_author = $this->config->project_author;
// we can only set these if the component was passed
$plugin->xml_description = "<h1>" . $plugin->official_name
. " (v." . $plugin->plugin_version
. ")</h1> <div style='clear: both;'></div>"
. $plugin->description . "<p>Created by <a href='" . trim(
(string) $this->config->project_website
) . "' target='_blank'>" . trim(
(string) OutputFilter::cleanText($project_author)
) . "</a><br /><small>Development started "
. Factory::getDate($plugin->created)->format("jS F, Y")
. "</small></p>";
// set xml discription
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_XML_DESCRIPTION',
$plugin->xml_description
);
// update the readme if set
if ($plugin->addreadme == 1 && !empty($plugin->readme))
{
$plugin->readme = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->readme))
);
}
else
{
$plugin->addreadme = 0;
unset($plugin->readme);
}
// open some base64 strings
if (!empty($plugin->main_class_code))
{
// set GUI mapper field
$guiMapper['field'] = 'main_class_code';
// base64 Decode main_class_code.
$plugin->main_class_code = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->main_class_code)
)
),
$guiMapper
);
}
// set the head :)
if ($plugin->add_head == 1 && !empty($plugin->head))
{
// set GUI mapper field
$guiMapper['field'] = 'head';
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->head)
)
),
$guiMapper
);
}
elseif (!empty($plugin->class_head))
{
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->class_head)
)
),
array(
'table' => 'class_extends',
'field' => 'head',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
unset($plugin->class_head);
// Check the plugin's code and header for each trait
foreach ($this->service_checks as $key => $info)
{
if (strpos($plugin->main_class_code, $key) !== false ||
strpos($plugin->main_class_code, $info['class']) !== false ||
strpos($plugin->header, $info['trait']) !== false)
{
$service_provider[] = Indent::_(4) . "\$plugin->{$info['method']}(\$container->get({$info['service']}::class));";
}
}
// Assign service provider if any services were added
if (!empty($service_provider))
{
$plugin->service_provider = implode(PHP_EOL, $service_provider);
}
// set the comment
if (!empty($plugin->comment))
{
// base64 Decode comment.
$plugin->comment = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->comment)
)
),
array(
'table' => 'class_extends',
'field' => 'comment',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
// start the config array
$plugin->config_fields = [];
// create the form arrays
$plugin->form_files = [];
$plugin->fieldsets_label = [];
$plugin->fieldsets_paths = [];
$plugin->add_rule_path = [];
$plugin->add_field_path = [];
// set global fields rule to default component path
$plugin->fields_rules_paths = 1;
// set the fields data
$plugin->fields = (isset($plugin->fields)
&& JsonHelper::check($plugin->fields))
? json_decode((string) $plugin->fields, true) : null;
if (ArrayHelper::check($plugin->fields))
{
// ket global key
$key = $plugin->key;
$dynamic_fields = array('fieldset' => 'basic',
'fields_name' => 'params',
'file' => 'config');
foreach ($plugin->fields as $n => &$form)
{
if (isset($form['fields'])
&& ArrayHelper::check(
$form['fields']
))
{
// make sure the dynamic_field is set to dynamic_value by default
foreach (
$dynamic_fields as $dynamic_field =>
$dynamic_value
)
{
if (!isset($form[$dynamic_field])
|| !StringHelper::check(
$form[$dynamic_field]
))
{
$form[$dynamic_field] = $dynamic_value;
}
else
{
if ('fields_name' === $dynamic_field
&& strpos((string) $form[$dynamic_field], '.')
!== false)
{
$form[$dynamic_field]
= $form[$dynamic_field];
}
else
{
$form[$dynamic_field]
= StringHelper::safe(
$form[$dynamic_field]
);
}
}
}
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// now build the form key
$unique = $form['file'] . $form['fields_name']
. $form['fieldset'];
}
else
{
// now build the form key
$unique = $form['fields_name']
. $form['fieldset'];
}
// set global fields rule path switchs
if ($plugin->fields_rules_paths == 1
&& isset($form['fields_rules_paths'])
&& $form['fields_rules_paths'] == 2)
{
$plugin->fields_rules_paths = 2;
}
// set where to path is pointing
$plugin->fieldsets_paths[$unique]
= $form['fields_rules_paths'];
// add the label if set to lang
if (isset($form['label'])
&& StringHelper::check(
$form['label']
))
{
$plugin->fieldsets_label[$unique]
= $this->language->key($form['label']);
}
// check for extra rule paths
if (isset($form['addrulepath'])
&& ArrayHelper::check($form['addrulepath']))
{
foreach ($form['addrulepath'] as $add_rule_path)
{
if (StringHelper::check($add_rule_path['path']))
{
$plugin->add_rule_path[$unique] = $add_rule_path['path'];
}
}
}
// check for extra field paths
if (isset($form['addfieldpath'])
&& ArrayHelper::check($form['addfieldpath']))
{
foreach ($form['addfieldpath'] as $add_field_path)
{
if (StringHelper::check($add_field_path['path']))
{
$plugin->add_field_path[$unique] = $add_field_path['path'];
}
}
}
// build the fields
$form['fields'] = array_map(
function ($field) use ($key, $unique) {
// make sure the alias and title is 0
$field['alias'] = 0;
$field['title'] = 0;
// set the field details
$this->field->set(
$field, $key, $key, $unique
);
// update the default if set
if (StringHelper::check(
$field['custom_value']
)
&& isset($field['settings']))
{
if (($old_default
= GetHelper::between(
$field['settings']->xml,
'default="', '"', false
)) !== false)
{
// replace old default
$field['settings']->xml
= str_replace(
'default="' . $old_default
. '"', 'default="'
. $field['custom_value'] . '"',
(string) $field['settings']->xml
);
}
else
{
// add the default (hmmm not ideal but okay it should work)
$field['settings']->xml
= 'default="'
. $field['custom_value'] . '" '
. $field['settings']->xml;
}
}
unset($field['custom_value']);
// return field
return $field;
}, array_values($form['fields'])
);
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// load the form file
if (!isset($plugin->form_files[$form['file']]))
{
$plugin->form_files[$form['file']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']]))
{
$plugin->form_files[$form['file']][$form['fields_name']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]))
{
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the global form file builder
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
else
{
// load the config form
if (!isset($plugin->config_fields[$form['fields_name']]))
{
$plugin->config_fields[$form['fields_name']]
= [];
}
if (!isset($plugin->config_fields[$form['fields_name']][$form['fieldset']]))
{
$plugin->config_fields[$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the config builder
$plugin->config_fields[$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
}
else
{
unset($plugin->fields[$n]);
}
}
}
unset($plugin->fields);
// set files and folders
$this->filesfolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method',
'php_script'
];
$addScriptTypes = [
'install',
'update',
'uninstall',
'construct'
];
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType})
&& $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$plugin->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $plugin->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
}
else
{
unset($plugin->{$scriptMethod . '_' . $scriptType});
$plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}
// add_sql
if ($plugin->add_sql == 1
&& StringHelper::check($plugin->sql))
{
$plugin->sql = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->sql))
);
}
else
{
unset($plugin->sql);
$plugin->add_sql = 0;
}
// add_sql_uninstall
if ($plugin->add_sql_uninstall == 1
&& StringHelper::check(
$plugin->sql_uninstall
))
{
$plugin->sql_uninstall = $this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->sql_uninstall)
)
);
}
else
{
unset($plugin->sql_uninstall);
$plugin->add_sql_uninstall = 0;
}
// update the URL of the update_server if set
if ($plugin->add_update_server == 1
&& StringHelper::check(
$plugin->update_server_url
))
{
$plugin->update_server_url = $this->placeholder->update_(
$this->customcode->update($plugin->update_server_url)
);
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($plugin->{'add_' . $server} == 1
&& is_numeric(
$plugin->{$server}
)
&& $plugin->{$server} > 0)
{
// get the server protocol
$plugin->{$server . '_protocol'}
= GetHelper::var(
'server', (int) $plugin->{$server}, 'id', 'protocol'
);
}
else
{
$plugin->{$server} = 0;
// only change this for sales server (update server can be added locally to the zip file)
if ('sales_server' === $server)
{
$plugin->{'add_' . $server} = 0;
}
$plugin->{$server . '_protocol'} = 0;
}
}
// old path (to remove)
$plugin->remove_file_paths = [];
$plugin->remove_file_paths[] = "/plugins/{$plugin->group}/{$plugin->context_name}/{$plugin->file_name}.php";
// set the update server stuff (TODO)
// update_server_xml_path
// update_server_xml_file_name
// rest globals
$this->config->build_target = $_backup_target;
$this->config->lang_target = $_backup_lang;
$this->config->set('lang_prefix', $_backup_langPrefix);
$this->placeholder->remove('Plugin_name');
$this->placeholder->remove('Plugin');
$this->placeholder->remove('plugin');
$this->placeholder->remove('Plugin_group');
$this->placeholder->remove('plugin_group');
$this->placeholder->remove('plugin.version');
$this->placeholder->remove('plugin_version');
$this->placeholder->remove('VERSION');
$this->placeholder->remove('DESCRIPTION');
$this->placeholder->remove('PLUGIN_NAME');
$this->data[$id] = $plugin;
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,891 @@
/**
* Compiler Joomla Plug-in's Data
*
* @var array
* @since 3.2.0
*/
protected array $data = [];
/**
* The Configure Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Customcode Class.
*
* @var Customcode
* @since 5.0.2
*/
protected Customcode $customcode;
/**
* The Gui Class.
*
* @var Gui
* @since 5.0.2
*/
protected Gui $gui;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Field Class.
*
* @var Field
* @since 5.0.2
*/
protected Field $field;
/**
* The Name Class.
*
* @var FieldName
* @since 5.0.2
*/
protected FieldName $fieldname;
/**
* The Filesfolders Class.
*
* @var Filesfolders
* @since 5.0.2
*/
protected Filesfolders $filesfolders;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Define the mappings of traits and classes to their respective methods and services
*
* @var array
* @since 5.0.2
**/
protected array $service_checks = [
'DatabaseAwareTrait' => [
'trait' => 'Joomla\Database\DatabaseAwareTrait',
'class' => 'Joomla__'.'_ae15e6b6_f7de_43ad_be4b_71499ae88f45___Power',
'method' => 'setDatabase',
'service' => 'Joomla__'.'_7bd29d76_73c9_4c07_a5da_4f7a32aff78f___Power'
],
'UserFactoryAwareTrait' => [
'trait' => 'Joomla\CMS\User\UserFactoryAwareTrait',
'class' => 'Joomla__'.'_a6b2c321_5de3_4425_b05f_e5340965fb80___Power',
'method' => 'setUserFactory',
'service' => 'Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power'
]
];
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Customcode $customcode The Customcode Class.
* @param Gui $gui The Gui Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Language Class.
* @param Field $field The Field Class.
* @param FieldName $fieldname The Name Class.
* @param Filesfolders $filesfolders The Filesfolders Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Customcode $customcode, Gui $gui,
Placeholder $placeholder, Language $language,
Field $field, FieldName $fieldname,
Filesfolders $filesfolders)
{
$this->config = $config;
$this->customcode = $customcode;
$this->gui = $gui;
$this->placeholder = $placeholder;
$this->language = $language;
$this->field = $field;
$this->fieldname = $fieldname;
$this->filesfolders = $filesfolders;
$this->db = Factory::getDbo();
}
/**
* Get the Joomla Plugin/s
*
* @param int|null $id the plugin id
*
* @return object|array|null if ID found it returns object, if no ID given it returns all set
* @since 3.2.0
*/
public function get(int $id = null)
{
if (is_null($id) && $this->exists())
{
return $this->data;
}
elseif ($this->exists($id))
{
return $this->data[$id];
}
return null;
}
/**
* Check if the Joomla Plugin/s exists
*
* @param int|null $id the plugin id
*
* @return bool if ID found it returns true, if no ID given it returns true if any are set
* @since 3.2.0
*/
public function exists(int $id = null): bool
{
if (is_null($id))
{
return ArrayHelper::check($this->data);
}
elseif (isset($this->data[$id]))
{
return true;
}
return $this->set($id);
}
/**
* Set the Joomla Plugin
*
* @param int $id the plugin id
*
* @return bool true on success
* @since 3.2.0
*/
public function set(int $id): bool
{
if (isset($this->data[$id]))
{
return true;
}
else
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->select('a.*');
$query->select(
$this->db->quoteName(
array(
'g.name',
'e.name',
'e.head',
'e.comment',
'e.id',
'f.addfiles',
'f.addfolders',
'f.addfilesfullpath',
'f.addfoldersfullpath',
'f.addurls',
'u.version_update',
'u.id'
), array(
'group',
'extends',
'class_head',
'comment',
'class_id',
'addfiles',
'addfolders',
'addfilesfullpath',
'addfoldersfullpath',
'addurls',
'version_update',
'version_update_id'
)
)
);
// from these tables
$query->from('#__componentbuilder_joomla_plugin AS a');
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_group', 'g'
) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group')
. ' = ' . $this->db->quoteName('g.id') . ')'
);
$query->join(
'LEFT',
$this->db->quoteName('#__componentbuilder_class_extends', 'e')
. ' ON (' . $this->db->quoteName('a.class_extends') . ' = '
. $this->db->quoteName('e.id') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_updates', 'u'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('u.joomla_plugin') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_files_folders_urls', 'f'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('f.joomla_plugin') . ')'
);
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
$query->where($this->db->quoteName('a.published') . ' >= 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
// get the plugin data
$plugin = $this->db->loadObject();
// tweak system to set stuff to the plugin domain
$_backup_target = $this->config->build_target;
$_backup_lang = $this->config->lang_target;
$_backup_langPrefix = $this->config->lang_prefix;
// set some keys
$plugin->target_type = 'pLuG!n';
$plugin->key = $plugin->id . '_' . $plugin->target_type;
// update to point to plugin
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
// set version if not set
if (empty($plugin->plugin_version))
{
$plugin->plugin_version = '1.0.0';
}
// set GUI mapper
$guiMapper = array('table' => 'joomla_plugin',
'id' => (int) $id, 'type' => 'php');
// update the name if it has dynamic values
$plugin->name = $this->placeholder->update_(
$this->customcode->update($plugin->name)
);
// update the name if it has dynamic values
$plugin->code_name
= ClassfunctionHelper::safe(
$plugin->name
);
// set official name
$plugin->official_name = ucwords(
$plugin->group . ' - ' . $plugin->name
);
// set lang prefix
$plugin->lang_prefix = PluginHelper::safeLangPrefix(
$plugin->code_name,
$plugin->group
);
// set langPrefix
$this->config->lang_prefix = $plugin->lang_prefix;
// set plugin class name
$plugin->class_name = ucfirst(
$plugin->code_name
);
// set plugin context name
$plugin->context_name = strtolower((string)
$plugin->code_name
);
// set plugin namespace
$plugin->namespace = $plugin->code_name;
// set plugin group namespace
$plugin->group_namespace = ucfirst(
$plugin->group
);
// set plugin install class name
$plugin->installer_class_name
= PluginHelper::safeInstallClassName(
$plugin->code_name,
$plugin->group
);
// set plugin folder name
$plugin->folder_name
= PluginHelper::safeFolderName(
$plugin->code_name,
$plugin->group
);
// set the zip name
$plugin->zip_name = $plugin->folder_name . '_v' . str_replace(
'.', '_', (string) $plugin->plugin_version
) . '__J' . $this->config->joomla_version;
// set plugin file name
$plugin->file_name = $plugin->context_name;
$plugin->class_file_name = $plugin->code_name;
// set plugin context
$plugin->context = $plugin->folder_name . '.' . $plugin->id;
// set official_name lang strings
$this->language->set(
$plugin->key, $this->config->lang_prefix, $plugin->official_name
);
// set some placeholder for this plugin
$this->placeholder->set('Plugin_name', $plugin->official_name);
$this->placeholder->set('PLUGIN_NAME', $plugin->official_name);
$this->placeholder->set('Plugin', ucfirst((string) $plugin->code_name));
$this->placeholder->set('plugin', strtolower((string) $plugin->code_name));
$this->placeholder->set('Plugin_group', ucfirst((string) $plugin->group));
$this->placeholder->set('plugin_group', strtolower((string) $plugin->group));
$this->placeholder->set('plugin.version', $plugin->plugin_version);
$this->placeholder->set('VERSION', $plugin->plugin_version);
$this->placeholder->set('plugin_version', str_replace(
'.', '_', (string) $plugin->plugin_version
));
// set description
$this->placeholder->set('DESCRIPTION', '');
if (!isset($plugin->description)
|| !StringHelper::check(
$plugin->description
))
{
$plugin->description = '';
}
else
{
$plugin->description = $this->placeholder->update_(
$this->customcode->update($plugin->description)
);
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_DESCRIPTION',
$plugin->description
);
// set description
$this->placeholder->set('DESCRIPTION', $plugin->description);
$plugin->description = '<p>' . $plugin->description . '</p>';
}
// get author name
$project_author = $this->config->project_author;
// we can only set these if the component was passed
$plugin->xml_description = "<h1>" . $plugin->official_name
. " (v." . $plugin->plugin_version
. ")</h1> <div style='clear: both;'></div>"
. $plugin->description . "<p>Created by <a href='" . trim(
(string) $this->config->project_website
) . "' target='_blank'>" . trim(
(string) OutputFilter::cleanText($project_author)
) . "</a><br /><small>Development started "
. Factory::getDate($plugin->created)->format("jS F, Y")
. "</small></p>";
// set xml discription
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_XML_DESCRIPTION',
$plugin->xml_description
);
// update the readme if set
if ($plugin->addreadme == 1 && !empty($plugin->readme))
{
$plugin->readme = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->readme))
);
}
else
{
$plugin->addreadme = 0;
unset($plugin->readme);
}
// open some base64 strings
if (!empty($plugin->main_class_code))
{
// set GUI mapper field
$guiMapper['field'] = 'main_class_code';
// base64 Decode main_class_code.
$plugin->main_class_code = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->main_class_code)
)
),
$guiMapper
);
}
// set the head :)
if ($plugin->add_head == 1 && !empty($plugin->head))
{
// set GUI mapper field
$guiMapper['field'] = 'head';
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->head)
)
),
$guiMapper
);
}
elseif (!empty($plugin->class_head))
{
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->class_head)
)
),
array(
'table' => 'class_extends',
'field' => 'head',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
unset($plugin->class_head);
// Check the plugin's code and header for each trait
foreach ($this->service_checks as $key => $info)
{
if (strpos($plugin->main_class_code, $key) !== false ||
strpos($plugin->main_class_code, $info['class']) !== false ||
strpos($plugin->header, $info['trait']) !== false)
{
$service_provider[] = Indent::_(4) . "\$plugin->{$info['method']}(\$container->get({$info['service']}::class));";
}
}
// Assign service provider if any services were added
if (!empty($service_provider))
{
$plugin->service_provider = implode(PHP_EOL, $service_provider);
}
// set the comment
if (!empty($plugin->comment))
{
// base64 Decode comment.
$plugin->comment = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->comment)
)
),
array(
'table' => 'class_extends',
'field' => 'comment',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
// start the config array
$plugin->config_fields = [];
// create the form arrays
$plugin->form_files = [];
$plugin->fieldsets_label = [];
$plugin->fieldsets_paths = [];
$plugin->add_rule_path = [];
$plugin->add_field_path = [];
// set global fields rule to default component path
$plugin->fields_rules_paths = 1;
// set the fields data
$plugin->fields = (isset($plugin->fields)
&& JsonHelper::check($plugin->fields))
? json_decode((string) $plugin->fields, true) : null;
if (ArrayHelper::check($plugin->fields))
{
// ket global key
$key = $plugin->key;
$dynamic_fields = array('fieldset' => 'basic',
'fields_name' => 'params',
'file' => 'config');
foreach ($plugin->fields as $n => &$form)
{
if (isset($form['fields'])
&& ArrayHelper::check(
$form['fields']
))
{
// make sure the dynamic_field is set to dynamic_value by default
foreach (
$dynamic_fields as $dynamic_field =>
$dynamic_value
)
{
if (!isset($form[$dynamic_field])
|| !StringHelper::check(
$form[$dynamic_field]
))
{
$form[$dynamic_field] = $dynamic_value;
}
else
{
if ('fields_name' === $dynamic_field
&& strpos((string) $form[$dynamic_field], '.')
!== false)
{
$form[$dynamic_field]
= $form[$dynamic_field];
}
else
{
$form[$dynamic_field]
= StringHelper::safe(
$form[$dynamic_field]
);
}
}
}
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// now build the form key
$unique = $form['file'] . $form['fields_name']
. $form['fieldset'];
}
else
{
// now build the form key
$unique = $form['fields_name']
. $form['fieldset'];
}
// set global fields rule path switchs
if ($plugin->fields_rules_paths == 1
&& isset($form['fields_rules_paths'])
&& $form['fields_rules_paths'] == 2)
{
$plugin->fields_rules_paths = 2;
}
// set where to path is pointing
$plugin->fieldsets_paths[$unique]
= $form['fields_rules_paths'];
// add the label if set to lang
if (isset($form['label'])
&& StringHelper::check(
$form['label']
))
{
$plugin->fieldsets_label[$unique]
= $this->language->key($form['label']);
}
// check for extra rule paths
if (isset($form['addrulepath'])
&& ArrayHelper::check($form['addrulepath']))
{
foreach ($form['addrulepath'] as $add_rule_path)
{
if (StringHelper::check($add_rule_path['path']))
{
$plugin->add_rule_path[$unique] = $add_rule_path['path'];
}
}
}
// check for extra field paths
if (isset($form['addfieldpath'])
&& ArrayHelper::check($form['addfieldpath']))
{
foreach ($form['addfieldpath'] as $add_field_path)
{
if (StringHelper::check($add_field_path['path']))
{
$plugin->add_field_path[$unique] = $add_field_path['path'];
}
}
}
// build the fields
$form['fields'] = array_map(
function ($field) use ($key, $unique) {
// make sure the alias and title is 0
$field['alias'] = 0;
$field['title'] = 0;
// set the field details
$this->field->set(
$field, $key, $key, $unique
);
// update the default if set
if (StringHelper::check(
$field['custom_value']
)
&& isset($field['settings']))
{
if (($old_default
= GetHelper::between(
$field['settings']->xml,
'default="', '"', false
)) !== false)
{
// replace old default
$field['settings']->xml
= str_replace(
'default="' . $old_default
. '"', 'default="'
. $field['custom_value'] . '"',
(string) $field['settings']->xml
);
}
else
{
// add the default (hmmm not ideal but okay it should work)
$field['settings']->xml
= 'default="'
. $field['custom_value'] . '" '
. $field['settings']->xml;
}
}
unset($field['custom_value']);
// return field
return $field;
}, array_values($form['fields'])
);
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// load the form file
if (!isset($plugin->form_files[$form['file']]))
{
$plugin->form_files[$form['file']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']]))
{
$plugin->form_files[$form['file']][$form['fields_name']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]))
{
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the global form file builder
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
else
{
// load the config form
if (!isset($plugin->config_fields[$form['fields_name']]))
{
$plugin->config_fields[$form['fields_name']]
= [];
}
if (!isset($plugin->config_fields[$form['fields_name']][$form['fieldset']]))
{
$plugin->config_fields[$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the config builder
$plugin->config_fields[$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
}
else
{
unset($plugin->fields[$n]);
}
}
}
unset($plugin->fields);
// set files and folders
$this->filesfolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method',
'php_script'
];
$addScriptTypes = [
'install',
'update',
'uninstall',
'construct'
];
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType})
&& $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$plugin->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $plugin->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
}
else
{
unset($plugin->{$scriptMethod . '_' . $scriptType});
$plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}
// add_sql
if ($plugin->add_sql == 1
&& StringHelper::check($plugin->sql))
{
$plugin->sql = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->sql))
);
}
else
{
unset($plugin->sql);
$plugin->add_sql = 0;
}
// add_sql_uninstall
if ($plugin->add_sql_uninstall == 1
&& StringHelper::check(
$plugin->sql_uninstall
))
{
$plugin->sql_uninstall = $this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->sql_uninstall)
)
);
}
else
{
unset($plugin->sql_uninstall);
$plugin->add_sql_uninstall = 0;
}
// update the URL of the update_server if set
if ($plugin->add_update_server == 1
&& StringHelper::check(
$plugin->update_server_url
))
{
$plugin->update_server_url = $this->placeholder->update_(
$this->customcode->update($plugin->update_server_url)
);
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($plugin->{'add_' . $server} == 1
&& is_numeric(
$plugin->{$server}
)
&& $plugin->{$server} > 0)
{
// get the server protocol
$plugin->{$server . '_protocol'}
= GetHelper::var(
'server', (int) $plugin->{$server}, 'id', 'protocol'
);
}
else
{
$plugin->{$server} = 0;
// only change this for sales server (update server can be added locally to the zip file)
if ('sales_server' === $server)
{
$plugin->{'add_' . $server} = 0;
}
$plugin->{$server . '_protocol'} = 0;
}
}
// old path (to remove)
$plugin->remove_file_paths = [];
$plugin->remove_file_paths[] = "/plugins/{$plugin->group}/{$plugin->context_name}/{$plugin->file_name}.php";
// set the update server stuff (TODO)
// update_server_xml_path
// update_server_xml_file_name
// rest globals
$this->config->build_target = $_backup_target;
$this->config->lang_target = $_backup_lang;
$this->config->set('lang_prefix', $_backup_langPrefix);
$this->placeholder->remove('Plugin_name');
$this->placeholder->remove('Plugin');
$this->placeholder->remove('plugin');
$this->placeholder->remove('Plugin_group');
$this->placeholder->remove('plugin_group');
$this->placeholder->remove('plugin.version');
$this->placeholder->remove('plugin_version');
$this->placeholder->remove('VERSION');
$this->placeholder->remove('DESCRIPTION');
$this->placeholder->remove('PLUGIN_NAME');
$this->data[$id] = $plugin;
return true;
}
}
return false;
}

View File

@ -0,0 +1,82 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "361e08c0-5916-4b77-b6a2-c16a769bbc40",
"implements": [
"8cc85656-a925-4a46-a49b-83c72167fd6a"
],
"load_selection": null,
"name": "Data",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Joomlaplugin.J4.Data",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",
"as": "default"
},
"use_selection1": {
"use": "313b43c4-98c3-4f62-9177-2d73ec8eba31",
"as": "default"
},
"use_selection2": {
"use": "1bd48df2-4f7e-4581-9fe9-4b54e59105e3",
"as": "default"
},
"use_selection3": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection4": {
"use": "8eee7df5-2775-41a9-9372-c46c5939a252",
"as": "default"
},
"use_selection5": {
"use": "d7ba2d5d-10b6-470d-978d-9f91ea65ee75",
"as": "default"
},
"use_selection6": {
"use": "9387215f-a965-4421-acf3-5e8f9d11382f",
"as": "FieldName"
},
"use_selection7": {
"use": "f4578c04-a81e-4218-b80d-b0612196eaf0",
"as": "default"
},
"use_selection8": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
},
"use_selection9": {
"use": "30c5b4c2-f75f-4d15-869a-f8bfedd87358",
"as": "default"
},
"use_selection10": {
"use": "3cf76fbf-fd95-4a33-878e-7aff6d36b7f6",
"as": "default"
},
"use_selection11": {
"use": "4b225c51-d293-48e4-b3f6-5136cf5c3f18",
"as": "default"
},
"use_selection12": {
"use": "1f28cb53-60d9-4db1-b517-3c7dc6b429ef",
"as": "default"
},
"use_selection13": {
"use": "db87c339-5bb6-4291-a7ef-2c48ea1b06bc",
"as": "default"
},
"use_selection14": {
"use": "a68c010b-e92e-47d5-8a44-d23cfddeb6c6",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Joomlaplugin.JoomlaFour.Data",
"description": "Joomla 4 Plug-in Data Class\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;\r\nuse Joomla\\CMS\\Filter\\OutputFilter;",
"composer": ""
}

View File

@ -0,0 +1,84 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Update (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Language**
```uml
@startuml
class Update << (F,LightGreen) >> #RoyalBlue {
# array $items
# $db
# $user
+ __construct()
+ set(int $id, string $target, ...) : void
+ execute(int $when = 1) : void
}
note right of Update::__construct
Constructor.
since: 5.0.2
end note
note right of Update::set
Add a language string to the existing language strings array for updating.
This method prepares and stores the update information for a language string
in the `items` array, which is later used by the `execute` method to update
the database.
since: 5.0.2
return: void
arguments:
int $id
string $target
array $targets
int $published
string $today
int $counter
end note
note right of Update::execute
Update the language placeholders in the database.
This method updates the language placeholders in the database if the number of items
meets or exceeds the specified threshold (`$when`). It constructs and executes an
update query for each set of values in the `items` array.
since: 5.0.2
return: void
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---375543cd_5f2a_4893_982e_a73eaa55360d---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,129 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
/**
* Compiler Update Existing Language Strings
*
* @since 5.0.2
*/
final class Update
{
/**
* The items to update
*
* @var array
* @since 5.0.2
**/
protected array $items = [];
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* User object
*
* @since 5.0.2
**/
protected $user;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
$this->user = Factory::getUser();
}
/**
* Add a language string to the existing language strings array for updating.
*
* This method prepares and stores the update information for a language string
* in the `items` array, which is later used by the `execute` method to update
* the database.
*
* @param int $id The ID of the language string.
* @param string $target The target field to be updated.
* @param array $targets The new values for the target field.
* @param int $published The published state.
* @param string $today The current date.
* @param int $counter The counter for the items array.
*
* @return void
* @since 5.0.2
*/
public function set(int $id, string $target, array $targets, int $published, string $today, int $counter): void
{
// Start the bucket for this language item.
$this->items[$counter] = [];
$this->items[$counter]['id'] = (int) $id;
// Prepare the conditions for the update query.
$this->items[$counter]['conditions'] = [];
$this->items[$counter]['conditions'][] = $this->db->quoteName('id') . ' = ' . $this->db->quote($id);
// Prepare the fields for the update query.
$this->items[$counter]['fields'] = [];
$this->items[$counter]['fields'][] = $this->db->quoteName($target) . ' = ' . $this->db->quote(json_encode($targets));
$this->items[$counter]['fields'][] = $this->db->quoteName('published') . ' = ' . $this->db->quote($published);
$this->items[$counter]['fields'][] = $this->db->quoteName('modified') . ' = ' . $this->db->quote($today);
$this->items[$counter]['fields'][] = $this->db->quoteName('modified_by') . ' = ' . $this->db->quote((int) $this->user->id);
}
/**
* Update the language placeholders in the database.
*
* This method updates the language placeholders in the database if the number of items
* meets or exceeds the specified threshold (`$when`). It constructs and executes an
* update query for each set of values in the `items` array.
*
* @param int $when The threshold count to determine when to update. Default is 1.
*
* @return void
* @since 5.0.2
*/
public function execute(int $when = 1): void
{
if (count((array) $this->items) >= $when)
{
foreach ($this->items as $values)
{
// Create a new query object.
$query = $this->db->getQuery(true);
// Prepare the update query.
$query->update($this->db->quoteName('#__componentbuilder_language_translation'))
->set($values['fields'])
->where($values['conditions']);
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
// Clear the items array.
$this->items = [];
}
}
}

View File

@ -0,0 +1,103 @@
/**
* The items to update
*
* @var array
* @since 5.0.2
**/
protected array $items = [];
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* User object
*
* @since 5.0.2
**/
protected $user;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
$this->user = Factory::getUser();
}
/**
* Add a language string to the existing language strings array for updating.
*
* This method prepares and stores the update information for a language string
* in the `items` array, which is later used by the `execute` method to update
* the database.
*
* @param int $id The ID of the language string.
* @param string $target The target field to be updated.
* @param array $targets The new values for the target field.
* @param int $published The published state.
* @param string $today The current date.
* @param int $counter The counter for the items array.
*
* @return void
* @since 5.0.2
*/
public function set(int $id, string $target, array $targets, int $published, string $today, int $counter): void
{
// Start the bucket for this language item.
$this->items[$counter] = [];
$this->items[$counter]['id'] = (int) $id;
// Prepare the conditions for the update query.
$this->items[$counter]['conditions'] = [];
$this->items[$counter]['conditions'][] = $this->db->quoteName('id') . ' = ' . $this->db->quote($id);
// Prepare the fields for the update query.
$this->items[$counter]['fields'] = [];
$this->items[$counter]['fields'][] = $this->db->quoteName($target) . ' = ' . $this->db->quote(json_encode($targets));
$this->items[$counter]['fields'][] = $this->db->quoteName('published') . ' = ' . $this->db->quote($published);
$this->items[$counter]['fields'][] = $this->db->quoteName('modified') . ' = ' . $this->db->quote($today);
$this->items[$counter]['fields'][] = $this->db->quoteName('modified_by') . ' = ' . $this->db->quote((int) $this->user->id);
}
/**
* Update the language placeholders in the database.
*
* This method updates the language placeholders in the database if the number of items
* meets or exceeds the specified threshold (`$when`). It constructs and executes an
* update query for each set of values in the `items` array.
*
* @param int $when The threshold count to determine when to update. Default is 1.
*
* @return void
* @since 5.0.2
*/
public function execute(int $when = 1): void
{
if (count((array) $this->items) >= $when)
{
foreach ($this->items as $values)
{
// Create a new query object.
$query = $this->db->getQuery(true);
// Prepare the update query.
$query->update($this->db->quoteName('#__componentbuilder_language_translation'))
->set($values['fields'])
->where($values['conditions']);
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
// Clear the items array.
$this->items = [];
}
}

View File

@ -0,0 +1,19 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "375543cd-5f2a-4893-982e-a73eaa55360d",
"implements": null,
"load_selection": null,
"name": "Update",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Language.Update",
"type": "final class",
"use_selection": null,
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Language.Update",
"description": "Compiler Update Existing Language Strings\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;",
"composer": ""
}

View File

@ -0,0 +1,55 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# interface InfusionInterface (Details)
> namespace: **VDM\Joomla\Componentbuilder\Interfaces\Plugin**
```uml
@startuml
interface InfusionInterface #Lavender {
+ set() : void
}
note right of InfusionInterface::set
Infuse the plugin data into the content.
This method processes each plugin in the data set, triggering events
before and after infusion, setting placeholders, and adding content
such as headers, classes, and XML configurations.
since: 5.0.2
return: void
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---40e17114_2193_4a61_9233_47b5f4193665---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,34 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Interfaces\Plugin;
/**
* Plug-in Infusion Interface
*
* @since 5.0.2
*/
interface InfusionInterface
{
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void;
}

View File

@ -0,0 +1,11 @@
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void;

View File

@ -0,0 +1,19 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "40e17114-2193-4a61-9233-47b5f4193665",
"implements": null,
"load_selection": null,
"name": "InfusionInterface",
"power_version": "1.0.0",
"system_name": "JCB.Interfaces.Plugin.InfusionInterface",
"type": "interface",
"use_selection": null,
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Interfaces.Plugin.InfusionInterface",
"description": "Plug-in Infusion Interface\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -13,8 +13,9 @@ namespace VDM\Joomla\Componentbuilder\Compiler\JoomlaFour;
use Joomla\CMS\Factory;
use Joomla\Registry\Registry;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Event\DispatcherInterface;
use Joomla\Registry\Registry;
use VDM\Joomla\Utilities\Component\Helper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface;
@ -35,9 +36,9 @@ final class Event implements EventInterface
protected $activePlugins = false;
/**
* The application to trigger and event TODO
* The dispatcher to get events
*
* @since 3.2.0
* @since 5.0.2
*/
protected $dispatcher;
@ -69,7 +70,7 @@ final class Event implements EventInterface
}
}
$this->dispatcher = Factory::getApplication();
$this->dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
}
/**
@ -89,8 +90,13 @@ final class Event implements EventInterface
{
try
{
// Trigger this compiler event.
$results = $this->dispatcher->triggerEvent($event, $data ?? []);
$data ??= [];
$listeners = $this->dispatcher->getListeners($event);
foreach ($listeners as $listener)
{
// Call the listener with the unpacked arguments
$listener(...$data);
}
}
catch (\Exception $e)
{

View File

@ -7,9 +7,9 @@
protected $activePlugins = false;
/**
* The application to trigger and event TODO
* The dispatcher to get events
*
* @since 3.2.0
* @since 5.0.2
*/
protected $dispatcher;
@ -41,7 +41,7 @@
}
}
$this->dispatcher = Factory::getApplication();
$this->dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
}
/**
@ -61,8 +61,13 @@
{
try
{
// Trigger this compiler event.
$results = $this->dispatcher->triggerEvent($event, $data ?? []);
$data ??= [];
$listeners = $this->dispatcher->getListeners($event);
foreach ($listeners as $listener)
{
// Call the listener with the unpacked arguments
$listener(...$data);
}
}
catch (\Exception $e)
{

View File

@ -21,6 +21,6 @@
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.JoomlaFour.Event",
"description": "Compiler Events\r\n\r\n@since 3.2.0",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Factory;\r\nuse Joomla\\Registry\\Registry;\r\nuse Joomla\\CMS\\Plugin\\PluginHelper;",
"head": "use Joomla\\CMS\\Factory;\r\nuse Joomla\\CMS\\Plugin\\PluginHelper;\r\nuse Joomla\\Event\\DispatcherInterface;\r\nuse Joomla\\Registry\\Registry;",
"composer": ""
}

View File

@ -6,12 +6,12 @@
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# class Fieldset (Details)
# final class Fieldset (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Language**
```uml
@startuml
class Fieldset #Gold {
class Fieldset << (F,LightGreen) >> #RoyalBlue {
# Language $language
# MetaData $metadata
# AccessSwitch $accessswitch

View File

@ -23,7 +23,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitchList;
*
* @since 3.2.0
*/
class Fieldset
final class Fieldset
{
/**
* The Language Class.

View File

@ -8,7 +8,7 @@
"name": "Fieldset",
"power_version": "1.0.0",
"system_name": "JCB.Compiler.Language.Fieldset",
"type": "class",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "8eee7df5-2775-41a9-9372-c46c5939a252",

View File

@ -0,0 +1,156 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class MainXML (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin**
```uml
@startuml
class MainXML << (F,LightGreen) >> #RoyalBlue {
# Config $config
# Language $language
# Set $set
# Purge $purge
# Translation $translation
# Multilingual $multilingual
# Event $event
# FieldsetExtension $fieldsetextension
# ContentOne $contentone
# Languages $languages
# BuilderMultilingual $buildermultilingual
# Counter $counter
# File $file
+ __construct(Config $config, Language $language, ...)
+ get(object $plugin) : string
# buildConfigFields(object $plugin) : array
# shouldAddComponentPath(object $plugin) : bool
# generateScriptAndSqlXml(object $plugin) : string
# generateLanguageXml(object $plugin, array $languageFiles) : string
# generateFileXml(object $plugin, array $languageFiles) : string
# generateConfigXml(object $plugin, array $configFields, ...) : string
# generateUpdateServerXml(object $plugin) : string
# generateLanguageFiles(object $plugin) : array
}
note right of MainXML::__construct
Constructor.
since: 5.0.2
arguments:
Config $config
Language $language
Set $set
Purge $purge
Translation $translation
Multilingual $multilingual
Event $event
FieldsetExtension $fieldsetextension
ContentOne $contentone
Languages $languages
BuilderMultilingual $buildermultilingual
Counter $counter
File $file
end note
note left of MainXML::get
Generates the main XML for the plugin.
since: 5.0.2
return: string
end note
note right of MainXML::buildConfigFields
Build configuration fields XML.
since: 5.0.2
return: array
end note
note left of MainXML::shouldAddComponentPath
Determine if the component path should be added.
since: 5.0.2
return: bool
end note
note right of MainXML::generateScriptAndSqlXml
Generate XML for script and SQL files.
since: 5.0.2
return: string
end note
note left of MainXML::generateLanguageXml
Generate XML for language files.
since: 5.0.2
return: string
end note
note right of MainXML::generateFileXml
Generate the XML for the files.
since: 5.0.2
return: string
end note
note left of MainXML::generateConfigXml
Generate XML for configuration fields.
since: 5.0.2
return: string
arguments:
object $plugin
array $configFields
bool $addComponentPath
end note
note right of MainXML::generateUpdateServerXml
Generate XML for update servers.
since: 5.0.2
return: string
end note
note left of MainXML::generateLanguageFiles
Generate language files.
since: 5.0.2
return: array
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---54e05f58_6538_42ec_ba46_b136f33e7cc7---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,570 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin;
use Joomla\CMS\Filesystem\Folder;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Language\Set;
use VDM\Joomla\Componentbuilder\Compiler\Language\Purge;
use VDM\Joomla\Componentbuilder\Compiler\Language\Translation;
use VDM\Joomla\Componentbuilder\Compiler\Language\Multilingual;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Languages;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Multilingual as BuilderMultilingual;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface;
/**
* Joomla 3 Plugin Main XML Class
*
* @since 5.0.2
*/
final class MainXML implements MainXMLInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Set Class.
*
* @var Set
* @since 5.0.2
*/
protected Set $set;
/**
* The Purge Class.
*
* @var Purge
* @since 5.0.2
*/
protected Purge $purge;
/**
* The Translation Class.
*
* @var Translation
* @since 5.0.2
*/
protected Translation $translation;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The FieldsetExtension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* The ContentOne Class.
*
* @var ContentOne
* @since 5.0.2
*/
protected ContentOne $contentone;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Multilingual Class.
*
* @var BuilderMultilingual
* @since 5.0.2
*/
protected BuilderMultilingual $buildermultilingual;
/**
* The Counter Class.
*
* @var Counter
* @since 5.0.2
*/
protected Counter $counter;
/**
* The File Class.
*
* @var File
* @since 5.0.2
*/
protected File $file;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Set $set The Set Class.
* @param Purge $purge The Purge Class.
* @param Translation $translation The Translation Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Event $event The EventInterface Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
* @param ContentOne $contentone The ContentOne Class.
* @param Languages $languages The Languages Class.
* @param BuilderMultilingual $buildermultilingual The Multilingual Class.
* @param Counter $counter The Counter Class.
* @param File $file The File Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language, Set $set, Purge $purge,
Translation $translation, Multilingual $multilingual,
Event $event, FieldsetExtension $fieldsetextension,
ContentOne $contentone, Languages $languages,
BuilderMultilingual $buildermultilingual,
Counter $counter, File $file)
{
$this->config = $config;
$this->language = $language;
$this->set = $set;
$this->purge = $purge;
$this->translation = $translation;
$this->multilingual = $multilingual;
$this->event = $event;
$this->fieldsetextension = $fieldsetextension;
$this->contentone = $contentone;
$this->languages = $languages;
$this->buildermultilingual = $buildermultilingual;
$this->counter = $counter;
$this->file = $file;
}
/**
* Generates the main XML for the plugin.
*
* @param object $plugin The plugin object.
*
* @return string The generated XML.
* @since 5.0.2
*/
public function get(object $plugin): string
{
$config_fields = $this->buildConfigFields($plugin);
$add_component_path = $this->shouldAddComponentPath($plugin);
$language_files = $this->generateLanguageFiles($plugin);
$xml = $this->generateScriptAndSqlXml($plugin);
$xml .= $this->generateLanguageXml($plugin, $language_files);
$xml .= $this->generateFileXml($plugin, $language_files);
$xml .= $this->generateConfigXml($plugin, $config_fields, $add_component_path);
$xml .= $this->generateUpdateServerXml($plugin);
return $xml;
}
/**
* Build configuration fields XML.
*
* @param object $plugin The plugin object.
*
* @return array The configuration fields.
* @since 5.0.2
*/
protected function buildConfigFields(object $plugin): array
{
$configFields = [];
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields))
{
return $configFields;
}
$dbKey = 'yy';
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$xmlFields = $this->fieldsetextension->get($plugin, $fields, $dbKey);
if (isset($xmlFields) && StringHelper::check($xmlFields))
{
$configFields["{$fieldName}{$fieldset}"] = $xmlFields;
}
$dbKey++;
}
}
return $configFields;
}
/**
* Determine if the component path should be added.
*
* @param object $plugin The plugin object.
*
* @return bool True if the component path should be added, false otherwise.
* @since 5.0.2
*/
protected function shouldAddComponentPath(object $plugin): bool
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields) ||
!isset($plugin->fieldsets_paths) || !ArrayHelper::check($plugin->fieldsets_paths))
{
return false;
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
if (isset($plugin->fieldsets_paths["{$fieldName}{$fieldset}"]) &&
$plugin->fieldsets_paths["{$fieldName}{$fieldset}"] == 1)
{
return true;
}
}
}
return false;
}
/**
* Generate XML for script and SQL files.
*
* @param object $plugin The plugin object.
*
* @return string The XML for script and SQL files.
* @since 5.0.2
*/
protected function generateScriptAndSqlXml(object $plugin): string
{
$xml = '';
if ($plugin->add_install_script)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Scripts to run on installation -->';
$xml .= PHP_EOL . Indent::_(1) . '<scriptfile>script.php</scriptfile>';
}
if ($plugin->add_sql)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on install -->';
$xml .= PHP_EOL . Indent::_(1) . '<install>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/install.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</install>';
}
if ($plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on uninstall -->';
$xml .= PHP_EOL . Indent::_(1) . '<uninstall>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/uninstall.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</uninstall>';
}
return $xml;
}
/**
* Generate XML for language files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for language files.
* @since 5.0.2
*/
protected function generateLanguageXml(object $plugin, array $languageFiles): string
{
$xml = '';
if (ArrayHelper::check($languageFiles))
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Language files -->';
$xml .= PHP_EOL . Indent::_(1) . '<languages folder="language">';
foreach ($languageFiles as $addTag)
{
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.ini</language>';
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.sys.ini</language>';
}
$xml .= PHP_EOL . Indent::_(1) . '</languages>';
}
return $xml;
}
/**
* Generate the XML for the files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for the files.
* @since 5.0.2
*/
protected function generateFileXml(object $plugin, array $languageFiles): string
{
$files = Folder::files($plugin->folder_path);
$folders = Folder::folders($plugin->folder_path);
$ignore = ['sql', 'language', 'script.php', "{$plugin->file_name}.xml", "{$plugin->file_name}.php"];
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Plugin files -->';
$xml .= PHP_EOL . Indent::_(1) . '<files>';
$xml .= PHP_EOL . Indent::_(2) . "<filename plugin=\"{$plugin->file_name}\">{$plugin->file_name}.php</filename>";
foreach ($files as $file)
{
if (!in_array($file, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<filename>{$file}</filename>";
}
}
if (!empty($languageFiles))
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>language</folder>';
}
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>sql</folder>';
}
foreach ($folders as $folder)
{
if (!in_array($folder, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<folder>{$folder}</folder>";
}
}
$xml .= PHP_EOL . Indent::_(1) . '</files>';
return $xml;
}
/**
* Generate XML for configuration fields.
*
* @param object $plugin The plugin object.
* @param array $configFields The configuration fields.
* @param bool $addComponentPath Whether to add the component path.
*
* @return string The XML for configuration fields.
* @since 5.0.2
*/
protected function generateConfigXml(object $plugin, array $configFields, bool $addComponentPath): string
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($configFields))
{
return '';
}
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Config parameters -->';
$xml .= $addComponentPath ? PHP_EOL . Indent::_(1) . '<config' : PHP_EOL . Indent::_(1) . '<config>';
if ($addComponentPath)
{
$xml .= PHP_EOL . Indent::_(2) . 'addrulepath="/administrator/components/com_' . $this->config->component_code_name . '/models/rules"';
$xml .= PHP_EOL . Indent::_(2) . 'addfieldpath="/administrator/components/com_' . $this->config->component_code_name . '/models/fields"';
$xml .= PHP_EOL . Indent::_(1) . '>';
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
$xml .= PHP_EOL . Indent::_(1) . "<fields name=\"{$fieldName}\">";
foreach ($fieldsets as $fieldset => $fields)
{
$label = $plugin->fieldsets_label["{$fieldName}{$fieldset}"] ?? $fieldset;
$xml .= PHP_EOL . Indent::_(1) . "<fieldset name=\"{$fieldset}\" label=\"{$label}\">";
if (isset($configFields["{$fieldName}{$fieldset}"]))
{
$xml .= $configFields["{$fieldName}{$fieldset}"];
}
$xml .= PHP_EOL . Indent::_(1) . '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . Indent::_(1) . '</config>';
return $xml;
}
/**
* Generate XML for update servers.
*
* @param object $plugin The plugin object.
*
* @return string The XML for update servers.
* @since 5.0.2
*/
protected function generateUpdateServerXml(object $plugin): string
{
$xml = '';
if ($plugin->add_update_server)
{
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Update servers -->';
$xml .= PHP_EOL . Indent::_(1) . '<updateservers>';
$xml .= PHP_EOL . Indent::_(2) . '<server type="extension" priority="1" name="' . $plugin->official_name . '">' . $plugin->update_server_url . '</server>';
$xml .= PHP_EOL . Indent::_(1) . '</updateservers>';
}
return $xml;
}
/**
* Generate language files.
*
* @param object $plugin The plugin object.
*
* @return array The language files.
* @since 5.0.2
*/
protected function generateLanguageFiles(object $plugin): array
{
$languageFiles = [];
if (!$this->language->exist($plugin->key))
{
return $languageFiles;
}
$langContent = $this->language->getTarget($plugin->key);
$this->event->trigger('jcb_ce_onBeforeBuildPluginLang', [&$plugin, &$langContent]);
$values = array_unique($langContent);
$this->buildermultilingual->set('plugins', $this->multilingual->get($values));
$langTag = $this->config->get('lang_tag', 'en-GB');
$this->languages->set("plugins.{$langTag}.all", $langContent);
$this->language->setTarget($plugin->key, null);
$this->set->execute($values, $plugin->id, 'plugins');
$this->purge->execute($values, $plugin->id, 'plugins');
$this->event->trigger('jcb_ce_onBeforeBuildPluginLangFiles', [&$plugin]);
if ($this->languages->IsArray('plugins'))
{
foreach ($this->languages->get('plugins') as $tag => $areas)
{
$tag = trim($tag);
foreach ($areas as $area => $languageStrings)
{
$fileName = "{$tag}.plg_" . strtolower((string)$plugin->group) . '_' . strtolower((string)$plugin->code_name) . '.ini';
$total = count($values);
if ($this->translation->check($tag, $languageStrings, $total, $fileName))
{
$lang = array_map(
fn($langString, $placeholder) => "{$placeholder}=\"{$langString}\"",
array_values($languageStrings),
array_keys($languageStrings)
);
$path = "{$plugin->folder_path}/language/{$tag}/";
if (!Folder::exists($path))
{
Folder::create($path);
$this->counter->folder++;
}
$this->file->write($path . $fileName, implode(PHP_EOL, $lang));
$this->file->write(
$path . $tag . '.plg_' . strtolower((string)$plugin->group) . '_' . strtolower((string)$plugin->code_name) . '.sys.ini',
implode(PHP_EOL, $lang)
);
$this->counter->line += count($lang);
unset($lang);
$languageFiles[$tag] = $tag;
}
}
}
}
return $languageFiles;
}
}

View File

@ -0,0 +1,526 @@
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Set Class.
*
* @var Set
* @since 5.0.2
*/
protected Set $set;
/**
* The Purge Class.
*
* @var Purge
* @since 5.0.2
*/
protected Purge $purge;
/**
* The Translation Class.
*
* @var Translation
* @since 5.0.2
*/
protected Translation $translation;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The FieldsetExtension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* The ContentOne Class.
*
* @var ContentOne
* @since 5.0.2
*/
protected ContentOne $contentone;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Multilingual Class.
*
* @var BuilderMultilingual
* @since 5.0.2
*/
protected BuilderMultilingual $buildermultilingual;
/**
* The Counter Class.
*
* @var Counter
* @since 5.0.2
*/
protected Counter $counter;
/**
* The File Class.
*
* @var File
* @since 5.0.2
*/
protected File $file;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Set $set The Set Class.
* @param Purge $purge The Purge Class.
* @param Translation $translation The Translation Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Event $event The EventInterface Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
* @param ContentOne $contentone The ContentOne Class.
* @param Languages $languages The Languages Class.
* @param BuilderMultilingual $buildermultilingual The Multilingual Class.
* @param Counter $counter The Counter Class.
* @param File $file The File Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language, Set $set, Purge $purge,
Translation $translation, Multilingual $multilingual,
Event $event, FieldsetExtension $fieldsetextension,
ContentOne $contentone, Languages $languages,
BuilderMultilingual $buildermultilingual,
Counter $counter, File $file)
{
$this->config = $config;
$this->language = $language;
$this->set = $set;
$this->purge = $purge;
$this->translation = $translation;
$this->multilingual = $multilingual;
$this->event = $event;
$this->fieldsetextension = $fieldsetextension;
$this->contentone = $contentone;
$this->languages = $languages;
$this->buildermultilingual = $buildermultilingual;
$this->counter = $counter;
$this->file = $file;
}
/**
* Generates the main XML for the plugin.
*
* @param object $plugin The plugin object.
*
* @return string The generated XML.
* @since 5.0.2
*/
public function get(object $plugin): string
{
$config_fields = $this->buildConfigFields($plugin);
$add_component_path = $this->shouldAddComponentPath($plugin);
$language_files = $this->generateLanguageFiles($plugin);
$xml = $this->generateScriptAndSqlXml($plugin);
$xml .= $this->generateLanguageXml($plugin, $language_files);
$xml .= $this->generateFileXml($plugin, $language_files);
$xml .= $this->generateConfigXml($plugin, $config_fields, $add_component_path);
$xml .= $this->generateUpdateServerXml($plugin);
return $xml;
}
/**
* Build configuration fields XML.
*
* @param object $plugin The plugin object.
*
* @return array The configuration fields.
* @since 5.0.2
*/
protected function buildConfigFields(object $plugin): array
{
$configFields = [];
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields))
{
return $configFields;
}
$dbKey = 'yy';
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$xmlFields = $this->fieldsetextension->get($plugin, $fields, $dbKey);
if (isset($xmlFields) && StringHelper::check($xmlFields))
{
$configFields["{$fieldName}{$fieldset}"] = $xmlFields;
}
$dbKey++;
}
}
return $configFields;
}
/**
* Determine if the component path should be added.
*
* @param object $plugin The plugin object.
*
* @return bool True if the component path should be added, false otherwise.
* @since 5.0.2
*/
protected function shouldAddComponentPath(object $plugin): bool
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields) ||
!isset($plugin->fieldsets_paths) || !ArrayHelper::check($plugin->fieldsets_paths))
{
return false;
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
if (isset($plugin->fieldsets_paths["{$fieldName}{$fieldset}"]) &&
$plugin->fieldsets_paths["{$fieldName}{$fieldset}"] == 1)
{
return true;
}
}
}
return false;
}
/**
* Generate XML for script and SQL files.
*
* @param object $plugin The plugin object.
*
* @return string The XML for script and SQL files.
* @since 5.0.2
*/
protected function generateScriptAndSqlXml(object $plugin): string
{
$xml = '';
if ($plugin->add_install_script)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Scripts to run on installation -->';
$xml .= PHP_EOL . Indent::_(1) . '<scriptfile>script.php</scriptfile>';
}
if ($plugin->add_sql)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on install -->';
$xml .= PHP_EOL . Indent::_(1) . '<install>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/install.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</install>';
}
if ($plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on uninstall -->';
$xml .= PHP_EOL . Indent::_(1) . '<uninstall>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/uninstall.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</uninstall>';
}
return $xml;
}
/**
* Generate XML for language files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for language files.
* @since 5.0.2
*/
protected function generateLanguageXml(object $plugin, array $languageFiles): string
{
$xml = '';
if (ArrayHelper::check($languageFiles))
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Language files -->';
$xml .= PHP_EOL . Indent::_(1) . '<languages folder="language">';
foreach ($languageFiles as $addTag)
{
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.ini</language>';
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.sys.ini</language>';
}
$xml .= PHP_EOL . Indent::_(1) . '</languages>';
}
return $xml;
}
/**
* Generate the XML for the files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for the files.
* @since 5.0.2
*/
protected function generateFileXml(object $plugin, array $languageFiles): string
{
$files = Folder::files($plugin->folder_path);
$folders = Folder::folders($plugin->folder_path);
$ignore = ['sql', 'language', 'script.php', "{$plugin->file_name}.xml", "{$plugin->file_name}.php"];
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Plugin files -->';
$xml .= PHP_EOL . Indent::_(1) . '<files>';
$xml .= PHP_EOL . Indent::_(2) . "<filename plugin=\"{$plugin->file_name}\">{$plugin->file_name}.php</filename>";
foreach ($files as $file)
{
if (!in_array($file, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<filename>{$file}</filename>";
}
}
if (!empty($languageFiles))
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>language</folder>';
}
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>sql</folder>';
}
foreach ($folders as $folder)
{
if (!in_array($folder, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<folder>{$folder}</folder>";
}
}
$xml .= PHP_EOL . Indent::_(1) . '</files>';
return $xml;
}
/**
* Generate XML for configuration fields.
*
* @param object $plugin The plugin object.
* @param array $configFields The configuration fields.
* @param bool $addComponentPath Whether to add the component path.
*
* @return string The XML for configuration fields.
* @since 5.0.2
*/
protected function generateConfigXml(object $plugin, array $configFields, bool $addComponentPath): string
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($configFields))
{
return '';
}
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Config parameters -->';
$xml .= $addComponentPath ? PHP_EOL . Indent::_(1) . '<config' : PHP_EOL . Indent::_(1) . '<config>';
if ($addComponentPath)
{
$xml .= PHP_EOL . Indent::_(2) . 'addrulepath="/administrator/components/com_' . $this->config->component_code_name . '/models/rules"';
$xml .= PHP_EOL . Indent::_(2) . 'addfieldpath="/administrator/components/com_' . $this->config->component_code_name . '/models/fields"';
$xml .= PHP_EOL . Indent::_(1) . '>';
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
$xml .= PHP_EOL . Indent::_(1) . "<fields name=\"{$fieldName}\">";
foreach ($fieldsets as $fieldset => $fields)
{
$label = $plugin->fieldsets_label["{$fieldName}{$fieldset}"] ?? $fieldset;
$xml .= PHP_EOL . Indent::_(1) . "<fieldset name=\"{$fieldset}\" label=\"{$label}\">";
if (isset($configFields["{$fieldName}{$fieldset}"]))
{
$xml .= $configFields["{$fieldName}{$fieldset}"];
}
$xml .= PHP_EOL . Indent::_(1) . '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . Indent::_(1) . '</config>';
return $xml;
}
/**
* Generate XML for update servers.
*
* @param object $plugin The plugin object.
*
* @return string The XML for update servers.
* @since 5.0.2
*/
protected function generateUpdateServerXml(object $plugin): string
{
$xml = '';
if ($plugin->add_update_server)
{
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Update servers -->';
$xml .= PHP_EOL . Indent::_(1) . '<updateservers>';
$xml .= PHP_EOL . Indent::_(2) . '<server type="extension" priority="1" name="' . $plugin->official_name . '">' . $plugin->update_server_url . '</server>';
$xml .= PHP_EOL . Indent::_(1) . '</updateservers>';
}
return $xml;
}
/**
* Generate language files.
*
* @param object $plugin The plugin object.
*
* @return array The language files.
* @since 5.0.2
*/
protected function generateLanguageFiles(object $plugin): array
{
$languageFiles = [];
if (!$this->language->exist($plugin->key))
{
return $languageFiles;
}
$langContent = $this->language->getTarget($plugin->key);
$this->event->trigger('jcb_ce_onBeforeBuildPluginLang', [&$plugin, &$langContent]);
$values = array_unique($langContent);
$this->buildermultilingual->set('plugins', $this->multilingual->get($values));
$langTag = $this->config->get('lang_tag', 'en-GB');
$this->languages->set("plugins.{$langTag}.all", $langContent);
$this->language->setTarget($plugin->key, null);
$this->set->execute($values, $plugin->id, 'plugins');
$this->purge->execute($values, $plugin->id, 'plugins');
$this->event->trigger('jcb_ce_onBeforeBuildPluginLangFiles', [&$plugin]);
if ($this->languages->IsArray('plugins'))
{
foreach ($this->languages->get('plugins') as $tag => $areas)
{
$tag = trim($tag);
foreach ($areas as $area => $languageStrings)
{
$fileName = "{$tag}.plg_" . strtolower((string)$plugin->group) . '_' . strtolower((string)$plugin->code_name) . '.ini';
$total = count($values);
if ($this->translation->check($tag, $languageStrings, $total, $fileName))
{
$lang = array_map(
fn($langString, $placeholder) => "{$placeholder}=\"{$langString}\"",
array_values($languageStrings),
array_keys($languageStrings)
);
$path = "{$plugin->folder_path}/language/{$tag}/";
if (!Folder::exists($path))
{
Folder::create($path);
$this->counter->folder++;
}
$this->file->write($path . $fileName, implode(PHP_EOL, $lang));
$this->file->write(
$path . $tag . '.plg_' . strtolower((string)$plugin->group) . '_' . strtolower((string)$plugin->code_name) . '.sys.ini',
implode(PHP_EOL, $lang)
);
$this->counter->line += count($lang);
unset($lang);
$languageFiles[$tag] = $tag;
}
}
}
}
return $languageFiles;
}

View File

@ -0,0 +1,90 @@
{
"add_head": "1",
"add_licensing_template": "2",
"extends": "",
"guid": "54e05f58-6538-42ec-ba46-b136f33e7cc7",
"implements": [
"97177ca9-a51a-4d24-81e1-8747b6e7d76c"
],
"load_selection": null,
"name": "MainXML",
"power_version": "1.0.0",
"system_name": "JCB.Architecture.J3.Plugin.MainXML",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "fa4bf18e-301e-42e3-91fb-6e0096c07adc",
"as": "default"
},
"use_selection1": {
"use": "8eee7df5-2775-41a9-9372-c46c5939a252",
"as": "default"
},
"use_selection2": {
"use": "058cfcd7-1f84-4cc6-8bcc-7672f316881d",
"as": "default"
},
"use_selection3": {
"use": "0b0e574c-aab4-4eaf-96d8-d7210d8ed93e",
"as": "default"
},
"use_selection4": {
"use": "344d36be-3949-4848-8cb0-e3d3d9d05c36",
"as": "default"
},
"use_selection5": {
"use": "263f0227-3cc2-4a88-9818-edb20081c30c",
"as": "default"
},
"use_selection6": {
"use": "20ed72b0-fcac-4344-aee1-8a65e3bf221d",
"as": "Event"
},
"use_selection7": {
"use": "23f459a4-7c2a-4cbf-b0a6-8a11954140a9",
"as": "default"
},
"use_selection8": {
"use": "adfbe68a-6d22-43e5-aee8-2787e8c47e75",
"as": "default"
},
"use_selection9": {
"use": "7526a39a-ada3-4499-8d75-81beff33f949",
"as": "default"
},
"use_selection10": {
"use": "a8c6158a-6fd2-476b-a5ea-c81f1ecd2356",
"as": "BuilderMultilingual"
},
"use_selection11": {
"use": "e6d871a6-bbe7-497d-af01-68f6bb9a87f4",
"as": "default"
},
"use_selection12": {
"use": "5c75b455-3d4c-452a-867e-e90424a64c88",
"as": "default"
},
"use_selection13": {
"use": "4e6ff11d-bebf-42f5-8fd7-b2f882857222",
"as": "default"
},
"use_selection14": {
"use": "a68c010b-e92e-47d5-8a44-d23cfddeb6c6",
"as": "default"
},
"use_selection15": {
"use": "0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a",
"as": "default"
},
"use_selection16": {
"use": "1f28cb53-60d9-4db1-b517-3c7dc6b429ef",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Architecture.JoomlaThree.Plugin.MainXML",
"description": "Joomla 3 Plugin Main XML Class\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "use Joomla\\CMS\\Filesystem\\Folder;",
"composer": ""
}

View File

@ -0,0 +1,61 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Provider (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin**
```uml
@startuml
class Provider << (F,LightGreen) >> #RoyalBlue {
# Placeholder $placeholder
# Builder $builder
+ __construct(Placeholder $placeholder, Builder $builder)
+ get(object $plugin) : string
}
note right of Provider::__construct
Constructor.
since: 5.0.2
end note
note right of Provider::get
Get the updated provider for the given plugin.
since: 5.0.2
return: string
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---60c3ccc5_36dc_4480_b5c4_252c37212f61---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,106 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface;
/**
* Plugin Provider Class for Joomla 4
*
* @since 5.0.2
*/
final class Provider implements ProviderInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$group = strtolower((string) $plugin->group);
$provider = [];
$provider[] = PHP_EOL . PHP_EOL . "return new class () implements ServiceProviderInterface {";
$provider[] = Indent::_(1) . "/**";
$provider[] = Indent::_(1) . "*" . Line::_(__Line__, __Class__)
. " Registers the service provider with a DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @param Container \$container The DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @return void";
$provider[] = Indent::_(1) . "* @since 4.3.0";
$provider[] = Indent::_(1) . "*/";
$provider[] = Indent::_(1) . "public function register(Container \$container)";
$provider[] = Indent::_(1) . "{";
$provider[] = Indent::_(2) . "\$container->set(";
$provider[] = Indent::_(3) . "PluginInterface::class,";
$provider[] = Indent::_(3) . "function (Container \$container) {";
$provider[] = Indent::_(4) . "\$plugin = new {$plugin->class_name}(";
$provider[] = Indent::_(5) . "\$container->get(DispatcherInterface::class),";
$provider[] = Indent::_(5) . "(array) PluginHelper::getPlugin('{$group}', '{$plugin->context_name}')";
$provider[] = Indent::_(4) . ");";
$provider[] = Indent::_(4) . "\$plugin->setApplication(Factory::getApplication());";
$provider[] = $plugin->service_provider ?? ''; // to add extra plug-in suff
$provider[] = Indent::_(4) . "return \$plugin;";
$provider[] = Indent::_(3) . "}";
$provider[] = Indent::_(2) . ");";
$provider[] = Indent::_(1) . "}";
$provider[] = "};";
return $this->placeholder->update(
implode(PHP_EOL, $provider). PHP_EOL,
$this->builder->allActive()
);
}
}

View File

@ -0,0 +1,76 @@
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$group = strtolower((string) $plugin->group);
$provider = [];
$provider[] = PHP_EOL . PHP_EOL . "return new class () implements ServiceProviderInterface {";
$provider[] = Indent::_(1) . "/**";
$provider[] = Indent::_(1) . "*" . Line::_(__Line__, __Class__)
. " Registers the service provider with a DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @param Container \$container The DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @return void";
$provider[] = Indent::_(1) . "* @since 4.3.0";
$provider[] = Indent::_(1) . "*/";
$provider[] = Indent::_(1) . "public function register(Container \$container)";
$provider[] = Indent::_(1) . "{";
$provider[] = Indent::_(2) . "\$container->set(";
$provider[] = Indent::_(3) . "PluginInterface::class,";
$provider[] = Indent::_(3) . "function (Container \$container) {";
$provider[] = Indent::_(4) . "\$plugin = new {$plugin->class_name}(";
$provider[] = Indent::_(5) . "\$container->get(DispatcherInterface::class),";
$provider[] = Indent::_(5) . "(array) PluginHelper::getPlugin('{$group}', '{$plugin->context_name}')";
$provider[] = Indent::_(4) . ");";
$provider[] = Indent::_(4) . "\$plugin->setApplication(Factory::getApplication());";
$provider[] = $plugin->service_provider ?? ''; // to add extra plug-in suff
$provider[] = Indent::_(4) . "return \$plugin;";
$provider[] = Indent::_(3) . "}";
$provider[] = Indent::_(2) . ");";
$provider[] = Indent::_(1) . "}";
$provider[] = "};";
return $this->placeholder->update(
implode(PHP_EOL, $provider). PHP_EOL,
$this->builder->allActive()
);
}

View File

@ -0,0 +1,38 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "60c3ccc5-36dc-4480-b5c4-252c37212f61",
"implements": [
"d6ae90a5-44b4-4ce4-aedc-86c90a242912"
],
"load_selection": null,
"name": "Provider",
"power_version": "1.0.0",
"system_name": "JCB.Architecture.J4.Plugin.Provider",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection1": {
"use": "adfbe68a-6d22-43e5-aee8-2787e8c47e75",
"as": "Builder"
},
"use_selection3": {
"use": "a68c010b-e92e-47d5-8a44-d23cfddeb6c6",
"as": "default"
},
"use_selection2": {
"use": "4e6ff11d-bebf-42f5-8fd7-b2f882857222",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Architecture.JoomlaFour.Plugin.Provider",
"description": "Plugin Provider Class for Joomla 4\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -0,0 +1,61 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Provider (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin**
```uml
@startuml
class Provider << (F,LightGreen) >> #RoyalBlue {
# Placeholder $placeholder
# Builder $builder
+ __construct(Placeholder $placeholder, Builder $builder)
+ get(object $plugin) : string
}
note right of Provider::__construct
Constructor.
since: 5.0.2
end note
note right of Provider::get
Get the updated provider for the given plugin.
since: 5.0.2
return: string
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---63865266_62e0_40bd_820c_e95449d12982---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,106 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface;
/**
* Plugin Provider Class for Joomla 5
*
* @since 5.0.2
*/
final class Provider implements ProviderInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$group = strtolower((string) $plugin->group);
$provider = [];
$provider[] = PHP_EOL . PHP_EOL . "return new class () implements ServiceProviderInterface {";
$provider[] = Indent::_(1) . "/**";
$provider[] = Indent::_(1) . "*" . Line::_(__Line__, __Class__)
. " Registers the service provider with a DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @param Container \$container The DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @return void";
$provider[] = Indent::_(1) . "* @since 4.3.0";
$provider[] = Indent::_(1) . "*/";
$provider[] = Indent::_(1) . "public function register(Container \$container)";
$provider[] = Indent::_(1) . "{";
$provider[] = Indent::_(2) . "\$container->set(";
$provider[] = Indent::_(3) . "PluginInterface::class,";
$provider[] = Indent::_(3) . "function (Container \$container) {";
$provider[] = Indent::_(4) . "\$plugin = new {$plugin->class_name}(";
$provider[] = Indent::_(5) . "\$container->get(DispatcherInterface::class),";
$provider[] = Indent::_(5) . "(array) PluginHelper::getPlugin('{$group}', '{$plugin->context_name}')";
$provider[] = Indent::_(4) . ");";
$provider[] = Indent::_(4) . "\$plugin->setApplication(Factory::getApplication());";
$provider[] = $plugin->service_provider ?? ''; // to add extra plug-in suff
$provider[] = Indent::_(4) . "return \$plugin;";
$provider[] = Indent::_(3) . "}";
$provider[] = Indent::_(2) . ");";
$provider[] = Indent::_(1) . "}";
$provider[] = "};";
return $this->placeholder->update(
implode(PHP_EOL, $provider). PHP_EOL,
$this->builder->allActive()
);
}
}

View File

@ -0,0 +1,76 @@
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$group = strtolower((string) $plugin->group);
$provider = [];
$provider[] = PHP_EOL . PHP_EOL . "return new class () implements ServiceProviderInterface {";
$provider[] = Indent::_(1) . "/**";
$provider[] = Indent::_(1) . "*" . Line::_(__Line__, __Class__)
. " Registers the service provider with a DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @param Container \$container The DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @return void";
$provider[] = Indent::_(1) . "* @since 4.3.0";
$provider[] = Indent::_(1) . "*/";
$provider[] = Indent::_(1) . "public function register(Container \$container)";
$provider[] = Indent::_(1) . "{";
$provider[] = Indent::_(2) . "\$container->set(";
$provider[] = Indent::_(3) . "PluginInterface::class,";
$provider[] = Indent::_(3) . "function (Container \$container) {";
$provider[] = Indent::_(4) . "\$plugin = new {$plugin->class_name}(";
$provider[] = Indent::_(5) . "\$container->get(DispatcherInterface::class),";
$provider[] = Indent::_(5) . "(array) PluginHelper::getPlugin('{$group}', '{$plugin->context_name}')";
$provider[] = Indent::_(4) . ");";
$provider[] = Indent::_(4) . "\$plugin->setApplication(Factory::getApplication());";
$provider[] = $plugin->service_provider ?? ''; // to add extra plug-in suff
$provider[] = Indent::_(4) . "return \$plugin;";
$provider[] = Indent::_(3) . "}";
$provider[] = Indent::_(2) . ");";
$provider[] = Indent::_(1) . "}";
$provider[] = "};";
return $this->placeholder->update(
implode(PHP_EOL, $provider). PHP_EOL,
$this->builder->allActive()
);
}

View File

@ -0,0 +1,38 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "63865266-62e0-40bd-820c-e95449d12982",
"implements": [
"d6ae90a5-44b4-4ce4-aedc-86c90a242912"
],
"load_selection": null,
"name": "Provider",
"power_version": "1.0.0",
"system_name": "JCB.Architecture.J5.Plugin.Provider",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection1": {
"use": "adfbe68a-6d22-43e5-aee8-2787e8c47e75",
"as": "Builder"
},
"use_selection2": {
"use": "a68c010b-e92e-47d5-8a44-d23cfddeb6c6",
"as": "default"
},
"use_selection3": {
"use": "4e6ff11d-bebf-42f5-8fd7-b2f882857222",
"as": "default"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Architecture.JoomlaFive.Plugin.Provider",
"description": "Plugin Provider Class for Joomla 5\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -143,6 +143,60 @@ final class Grep extends ExtendingGrep implements GrepInterface
// set the git details in params
$power->main_class_code = $code;
}
// set the git details in params
$path_guid = $path->guid ?? null;
if ($path_guid !== null)
{
// get the Settings meta
if (($meta = $this->contents->metadata($path->organisation, $path->repository, $path->index->{$guid}->settings, $branch)) !== null &&
isset($meta->sha))
{
if (isset($power->params) && is_object($power->params) &&
isset($power->params->source) && is_array($power->params->source))
{
$power->params->source[$path_guid . '-settings'] = $meta->sha;
}
else
{
$power->params = (object) [
'source' => [$path_guid . '-settings' => $meta->sha]
];
}
}
// get the power meta
if (($meta = $this->contents->metadata($path->organisation, $path->repository, $path->index->{$guid}->power, $branch)) !== null &&
isset($meta->sha))
{
if (isset($power->params) && is_object($power->params) &&
isset($power->params->source) && is_array($power->params->source))
{
$power->params->source[$path_guid . '-power'] = $meta->sha;
}
else
{
$power->params = (object) [
'source' => [$path_guid . '-power' => $meta->sha]
];
}
}
// get the README meta
if (($meta = $this->contents->metadata($path->organisation, $path->repository, $path->index->{$guid}->path . '/README.md', $branch)) !== null &&
isset($meta->sha))
{
if (isset($power->params) && is_object($power->params) &&
isset($power->params->source) && is_array($power->params->source))
{
$power->params->source[$path_guid . '-readme'] = $meta->sha;
}
else
{
$power->params = (object) [
'source' => [$path_guid . '-readme' => $meta->sha]
];
}
}
}
}
// reset back to the global base and token

View File

@ -110,6 +110,60 @@
// set the git details in params
$power->main_class_code = $code;
}
// set the git details in params
$path_guid = $path->guid ?? null;
if ($path_guid !== null)
{
// get the Settings meta
if (($meta = $this->contents->metadata($path->organisation, $path->repository, $path->index->{$guid}->settings, $branch)) !== null &&
isset($meta->sha))
{
if (isset($power->params) && is_object($power->params) &&
isset($power->params->source) && is_array($power->params->source))
{
$power->params->source[$path_guid . '-settings'] = $meta->sha;
}
else
{
$power->params = (object) [
'source' => [$path_guid . '-settings' => $meta->sha]
];
}
}
// get the power meta
if (($meta = $this->contents->metadata($path->organisation, $path->repository, $path->index->{$guid}->power, $branch)) !== null &&
isset($meta->sha))
{
if (isset($power->params) && is_object($power->params) &&
isset($power->params->source) && is_array($power->params->source))
{
$power->params->source[$path_guid . '-power'] = $meta->sha;
}
else
{
$power->params = (object) [
'source' => [$path_guid . '-power' => $meta->sha]
];
}
}
// get the README meta
if (($meta = $this->contents->metadata($path->organisation, $path->repository, $path->index->{$guid}->path . '/README.md', $branch)) !== null &&
isset($meta->sha))
{
if (isset($power->params) && is_object($power->params) &&
isset($power->params->source) && is_array($power->params->source))
{
$power->params->source[$path_guid . '-readme'] = $meta->sha;
}
else
{
$power->params = (object) [
'source' => [$path_guid . '-readme' => $meta->sha]
];
}
}
}
}
// reset back to the global base and token

View File

@ -351,7 +351,7 @@ final class Settings implements SettingsInterface
$this->config->get('footable', false))
{
$this->addImportViewFolder();
$this->addPhpSpreadsheetFolder();
// $this->addPhpSpreadsheetFolder(); // soon
$this->addUikitFolder();
$this->addFooTableFolder();
}

View File

@ -315,7 +315,7 @@
$this->config->get('footable', false))
{
$this->addImportViewFolder();
$this->addPhpSpreadsheetFolder();
// $this->addPhpSpreadsheetFolder(); // soon
$this->addUikitFolder();
$this->addFooTableFolder();
}

View File

@ -0,0 +1,61 @@
```
██████╗ ██████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗
██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝
██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗
██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║
╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝
```
# final class Provider (Details)
> namespace: **VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin**
```uml
@startuml
class Provider << (F,LightGreen) >> #RoyalBlue {
# Placeholder $placeholder
# Builder $builder
+ __construct(Placeholder $placeholder, Builder $builder)
+ get(object $plugin) : string
}
note right of Provider::__construct
Constructor.
since: 5.0.2
end note
note right of Provider::get
Get the updated provider for the given plugin.
since: 5.0.2
return: string
end note
@enduml
```
The Power feature in JCB allows you to write PHP classes and their implementations, making it easy to include them in your Joomla project. JCB handles linking, autoloading, namespacing, and folder structure creation for you.
By using the SPK (Super Power Key) in your custom code (replacing the class name in your code with the SPK), JCB will automatically pull the power from the repository into your project. This makes it available in your JCB instance, allowing you to edit it and include the class in your generated Joomla component.
JCB uses placeholders like [[[`NamespacePrefix`]]] and [[[`ComponentNamespace`]]] in namespacing to prevent collisions and improve reusability across different JCB systems. You can also set the **JCB powers path** globally or per component under the **Dynamic Integration** tab, providing flexibility and easy maintainability.
To add this specific Power to your project in JCB:
> simply use this SPK
```
Super---6dd2d394_8dde_4eb7_8505_cd7d345c49e3---Power
```
> remember to replace the `---` with `___` to activate this Power in your code
---
```
██╗ ██████╗██████╗
██║██╔════╝██╔══██╗
██║██║ ██████╔╝
██ ██║██║ ██╔══██╗
╚█████╔╝╚██████╗██████╔╝
╚════╝ ╚═════╝╚═════╝
```
> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)

View File

@ -0,0 +1,71 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface;
/**
* Plugin Provider Class for Joomla 3
*
* @since 5.0.2
*/
final class Provider implements ProviderInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
return ''; // no provider in Joomla 3
}
}

View File

@ -0,0 +1,43 @@
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
return ''; // no provider in Joomla 3
}

View File

@ -0,0 +1,30 @@
{
"add_head": "0",
"add_licensing_template": "2",
"extends": "",
"guid": "6dd2d394-8dde-4eb7-8505-cd7d345c49e3",
"implements": [
"d6ae90a5-44b4-4ce4-aedc-86c90a242912"
],
"load_selection": null,
"name": "Provider",
"power_version": "1.0.0",
"system_name": "JCB.Architecture.J3.Plugin.Provider",
"type": "final class",
"use_selection": {
"use_selection0": {
"use": "06453ada-e370-49f0-b262-e3f5a8ed0c2c",
"as": "default"
},
"use_selection1": {
"use": "adfbe68a-6d22-43e5-aee8-2787e8c47e75",
"as": "Builder"
}
},
"extendsinterfaces": null,
"namespace": "[[[NamespacePrefix]]]\\Joomla\\[[[ComponentNamespace]]].Compiler.Architecture.JoomlaThree.Plugin.Provider",
"description": "Plugin Provider Class for Joomla 3\r\n\r\n@since 5.0.2",
"licensing_template": "\/**\r\n * @package Joomla.Component.Builder\r\n *\r\n * @created 4th September, 2022\r\n * @author Llewellyn van der Merwe <https:\/\/dev.vdm.io>\r\n * @git Joomla Component Builder <https:\/\/git.vdm.dev\/joomla\/Component-Builder>\r\n * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.\r\n * @license GNU General Public License version 2 or later; see LICENSE.txt\r\n *\/\r\n",
"head": "",
"composer": ""
}

View File

@ -72,7 +72,7 @@ class Autoloader
*
* @param Power $power The Power Class.
* @param Config $config The Config Class.
* @param Content $content The ContentOne Class.
* @param Content $content The Content One Class.
*
* @since 3.2.0
*/

View File

@ -43,7 +43,7 @@
*
* @param Power $power The Power Class.
* @param Config $config The Config Class.
* @param Content $content The ContentOne Class.
* @param Content $content The Content One Class.
*
* @since 3.2.0
*/

View File

@ -21,6 +21,11 @@ class InstallScript << (F,LightGreen) >> #RoyalBlue {
# array $uninstall
# bool $preflightActive
# bool $postflightActive
# array $removeFilePaths
# array $removeFolderPaths
# $app
# array $deleteFiles
# array $deleteFolders
+ get(object $extension) : string
# rest() : void
# build() : string
@ -28,6 +33,7 @@ class InstallScript << (F,LightGreen) >> #RoyalBlue {
# construct() : string
# main(string $name) : string
# flight(string $name) : string
# removeFiles() : string
}
note right of InstallScript::get
@ -37,7 +43,7 @@ note right of InstallScript::get
return: string
end note
note right of InstallScript::rest
note left of InstallScript::rest
Reset all bucket at the start of each build
since: 3.2.0
@ -51,7 +57,7 @@ note right of InstallScript::build
return: string
end note
note right of InstallScript::head
note left of InstallScript::head
get install script head
since: 3.2.0
@ -65,7 +71,7 @@ note right of InstallScript::construct
return: string
end note
note right of InstallScript::main
note left of InstallScript::main
build main methods
since: 3.2.0
@ -78,6 +84,13 @@ note right of InstallScript::flight
since: 3.2.0
return: string
end note
note left of InstallScript::removeFiles
build remove files methods
since: 5.0.2
return: string
end note
@enduml
```

View File

@ -115,6 +115,22 @@ final class InstallScript implements GetScriptInterface
*/
protected array $postflightBucket = ['install' => [], 'uninstall' => [], 'discover_install' => [], 'update' => []];
/**
* The paths of the old plugin class files
*
* @var array
* @since 5.0.2
*/
protected array $removeFilePaths = [];
/**
* The paths of the old plugin folders
*
* @var array
* @since 5.0.2
*/
protected array $removeFolderPaths = [];
/**
* get install script
*
@ -128,6 +144,10 @@ final class InstallScript implements GetScriptInterface
// purge the object
$this->rest();
// set the remove path
$this->removeFilePaths = $extension->remove_file_paths ?? [];
$this->removeFolderPaths = $extension->remove_folder_paths ?? [];
// loop over methods and types
foreach ($this->methods as $method)
{
@ -171,6 +191,8 @@ final class InstallScript implements GetScriptInterface
*/
protected function rest(): void
{
$this->removeFilePaths = [];
$this->removeFolderPaths = [];
$this->construct = [];
$this->install = [];
$this->update = [];
@ -210,6 +232,9 @@ final class InstallScript implements GetScriptInterface
// load postflight method if set
$script .= $this->flight('postflight');
// load remove files method
$script .= $this->removeFiles();
// close the class
$script .= PHP_EOL . '}' . PHP_EOL;
@ -229,9 +254,11 @@ final class InstallScript implements GetScriptInterface
// start build
$script = PHP_EOL . 'use Joomla\CMS\Factory;';
$script .= PHP_EOL . 'use Joomla\CMS\Version;';
$script .= PHP_EOL . 'use Joomla\CMS\Installer\InstallerAdapter;';
$script .= PHP_EOL . 'use Joomla\CMS\Language\Text;';
$script .= PHP_EOL . 'use Joomla\CMS\Filesystem\File;';
$script .= PHP_EOL . 'use Joomla\CMS\Filesystem\Folder;' . PHP_EOL;
$script .= PHP_EOL . 'use Joomla\Filesystem\File;';
$script .= PHP_EOL . 'use Joomla\Filesystem\Folder;' . PHP_EOL;
$script .= PHP_EOL . '/**';
$script .= PHP_EOL . ' * ' . $extension->official_name
. ' script file.';
@ -252,26 +279,87 @@ final class InstallScript implements GetScriptInterface
*/
protected function construct(): string
{
// return empty string if not set
if (!ArrayHelper::check($this->construct))
{
return '';
}
// the __construct script
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script = PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' The CMS Application.';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @since 4.4.2';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected $app;';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' A list of files to be deleted';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @var array';
$script .= PHP_EOL . Indent::_(1) . ' * @since 3.6';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected array $deleteFiles = [];';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' A list of folders to be deleted';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @var array';
$script .= PHP_EOL . Indent::_(1) . ' * @since 3.6';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected array $deleteFolders = [];';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' * Constructor';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1)
. 'public function __construct($adapter)';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->construct);
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
. ' get application';
$script .= PHP_EOL . Indent::_(2)
. '$this->app = Factory::getApplication();' . PHP_EOL;
if (ArrayHelper::check($this->construct))
{
$script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->construct);
}
// check if custom remove file is set
if ($this->removeFilePaths !== [] && strpos($script, '$this->deleteFiles') === false)
{
// add the default delete files
foreach ($this->removeFilePaths as $filePath)
{
$script .= PHP_EOL . Indent::_(2) . "if (is_file(JPATH_ROOT . '$filePath'))";
$script .= PHP_EOL . Indent::_(2) . "{";
$script .= PHP_EOL . Indent::_(3) . "\$this->deleteFiles[] = '$filePath';";
$script .= PHP_EOL . Indent::_(2) . "}";
}
}
// check if custom remove file is set
if ($this->removeFolderPaths !== [] && strpos($script, '$this->deleteFolders') === false)
{
// add the default delete folders
foreach ($this->removeFolderPaths as $folderPath)
{
$script .= PHP_EOL . Indent::_(2) . "if (is_dir(JPATH_ROOT . '$folderPath'))";
$script .= PHP_EOL . Indent::_(2) . "{";
$script .= PHP_EOL . Indent::_(3) . "\$this->deleteFolders[] = '$folderPath';";
$script .= PHP_EOL . Indent::_(2) . "}";
}
}
// close the function
$script .= PHP_EOL . Indent::_(1) . '}';
// add remove files
$this->preflightBucket['bottom'][] = Indent::_(2) . '//' . Line::_(__Line__, __Class__)
.' remove old files and folders';
$this->preflightBucket['bottom'][] = Indent::_(2) . '$this->removeFiles();';
return $script;
}
@ -295,7 +383,7 @@ final class InstallScript implements GetScriptInterface
$script .= PHP_EOL . Indent::_(1) . " * Called on $name";
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @return boolean True on success';
@ -325,12 +413,6 @@ final class InstallScript implements GetScriptInterface
*/
protected function flight(string $name): string
{
// return empty string if not set
if (empty($this->{$name . 'Active'}))
{
return '';
}
// the pre/post function types
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1)
@ -339,7 +421,7 @@ final class InstallScript implements GetScriptInterface
$script .= PHP_EOL . Indent::_(1)
. ' * @param string $route Which action is happening (install|uninstall|discover_install|update)';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @return boolean True on success';
@ -348,9 +430,9 @@ final class InstallScript implements GetScriptInterface
. $name . '($route, $adapter)';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
. ' get application';
. ' set application to local method var, just use $this->app in future [we will drop $app in J6]';
$script .= PHP_EOL . Indent::_(2)
. '$app = Factory::getApplication();' . PHP_EOL;
. '$app = $this->app;' . PHP_EOL;
// add the default version check (TODO) must make this dynamic
if ('preflight' === $name)
@ -358,37 +440,88 @@ final class InstallScript implements GetScriptInterface
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
.' the default for both install and update';
$script .= PHP_EOL . Indent::_(2)
. '$jversion = new JVersion();';
. '$jversion = new Version();';
$script .= PHP_EOL . Indent::_(2)
. "if (!\$jversion->isCompatible('3.8.0'))";
. "if (!\$jversion->isCompatible('5.0.0'))";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3)
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 3.8.0 before continuing!', 'error');";
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 5.0.0 before continuing!', 'error');";
$script .= PHP_EOL . Indent::_(3) . 'return false;';
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
}
// now add the scripts
foreach ($this->{$name . 'Bucket'} as $route => $_script)
if (!empty($this->{$name . 'Active'}))
{
if (ArrayHelper::check($_script))
// now add the scripts
foreach ($this->{$name . 'Bucket'} as $route => $_script)
{
// set the if and script
$script .= PHP_EOL . Indent::_(2) . "if ('" . $route
. "' === \$route)";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . implode(
PHP_EOL . PHP_EOL, $_script
);
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
if (ArrayHelper::check($_script) && $route !== 'bottom')
{
// set the if and script
$script .= PHP_EOL . Indent::_(2) . "if ('" . $route
. "' === \$route)";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . implode(
PHP_EOL . PHP_EOL, $_script
);
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
}
}
}
if (isset($this->{$name . 'Bucket'}['bottom']) && ArrayHelper::check($this->{$name . 'Bucket'}['bottom']))
{
$script .= PHP_EOL . implode(
PHP_EOL , $this->{$name . 'Bucket'}['bottom']
) . PHP_EOL;
}
// return true
$script .= PHP_EOL . Indent::_(2) . 'return true;';
// close the function
$script .= PHP_EOL . Indent::_(1) . '}';
return $script;
}
/**
* build remove files methods
*
* @return string
* @since 5.0.2
*/
protected function removeFiles(): string
{
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' * Remove the files and folders in the given array from';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @return void';
$script .= PHP_EOL . Indent::_(1) . ' * @since 5.0.2';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected function removeFiles()';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . Indent::_(2) . 'if (!empty($this->deleteFiles))';
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3) . 'foreach ($this->deleteFiles as $file)';
$script .= PHP_EOL . Indent::_(3) . '{';
$script .= PHP_EOL . Indent::_(4) . 'if (is_file(JPATH_ROOT . $file) && !File::delete(JPATH_ROOT . $file))';
$script .= PHP_EOL . Indent::_(4) . '{';
$script .= PHP_EOL . Indent::_(5) . 'echo Text::sprintf(\'JLIB_INSTALLER_ERROR_FILE_FOLDER\', $file) . \'<br>\';';
$script .= PHP_EOL . Indent::_(4) . '}';
$script .= PHP_EOL . Indent::_(3) . '}';
$script .= PHP_EOL . Indent::_(2) . '}';
$script .= PHP_EOL . PHP_EOL . Indent::_(2) . 'if (!empty($this->deleteFolders))';
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3) . 'foreach ($this->deleteFolders as $folder)';
$script .= PHP_EOL . Indent::_(3) . '{';
$script .= PHP_EOL . Indent::_(4) . 'if (is_dir(JPATH_ROOT . $folder) && !Folder::delete(JPATH_ROOT . $folder))';
$script .= PHP_EOL . Indent::_(4) . '{';
$script .= PHP_EOL . Indent::_(5) . 'echo Text::sprintf(\'JLIB_INSTALLER_ERROR_FILE_FOLDER\', $folder) . \'<br>\';';
$script .= PHP_EOL . Indent::_(4) . '}';
$script .= PHP_EOL . Indent::_(3) . '}';
$script .= PHP_EOL . Indent::_(2) . '}';
$script .= PHP_EOL . Indent::_(1) . '}';
return $script;
}
}

View File

@ -86,6 +86,22 @@
*/
protected array $postflightBucket = ['install' => [], 'uninstall' => [], 'discover_install' => [], 'update' => []];
/**
* The paths of the old plugin class files
*
* @var array
* @since 5.0.2
*/
protected array $removeFilePaths = [];
/**
* The paths of the old plugin folders
*
* @var array
* @since 5.0.2
*/
protected array $removeFolderPaths = [];
/**
* get install script
*
@ -99,6 +115,10 @@
// purge the object
$this->rest();
// set the remove path
$this->removeFilePaths = $extension->remove_file_paths ?? [];
$this->removeFolderPaths = $extension->remove_folder_paths ?? [];
// loop over methods and types
foreach ($this->methods as $method)
{
@ -142,6 +162,8 @@
*/
protected function rest(): void
{
$this->removeFilePaths = [];
$this->removeFolderPaths = [];
$this->construct = [];
$this->install = [];
$this->update = [];
@ -181,6 +203,9 @@
// load postflight method if set
$script .= $this->flight('postflight');
// load remove files method
$script .= $this->removeFiles();
// close the class
$script .= PHP_EOL . '}' . PHP_EOL;
@ -200,9 +225,11 @@
// start build
$script = PHP_EOL . 'use Joomla\CMS\Factory;';
$script .= PHP_EOL . 'use Joomla\CMS\Version;';
$script .= PHP_EOL . 'use Joomla\CMS\Installer\InstallerAdapter;';
$script .= PHP_EOL . 'use Joomla\CMS\Language\Text;';
$script .= PHP_EOL . 'use Joomla\CMS\Filesystem\File;';
$script .= PHP_EOL . 'use Joomla\CMS\Filesystem\Folder;' . PHP_EOL;
$script .= PHP_EOL . 'use Joomla\Filesystem\File;';
$script .= PHP_EOL . 'use Joomla\Filesystem\Folder;' . PHP_EOL;
$script .= PHP_EOL . '/**';
$script .= PHP_EOL . ' * ' . $extension->official_name
. ' script file.';
@ -223,26 +250,87 @@
*/
protected function construct(): string
{
// return empty string if not set
if (!ArrayHelper::check($this->construct))
{
return '';
}
// the __construct script
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script = PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' The CMS Application.';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @since 4.4.2';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected $app;';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' A list of files to be deleted';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @var array';
$script .= PHP_EOL . Indent::_(1) . ' * @since 3.6';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected array $deleteFiles = [];';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' A list of folders to be deleted';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @var array';
$script .= PHP_EOL . Indent::_(1) . ' * @since 3.6';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected array $deleteFolders = [];';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' * Constructor';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1)
. 'public function __construct($adapter)';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->construct);
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
. ' get application';
$script .= PHP_EOL . Indent::_(2)
. '$this->app = Factory::getApplication();' . PHP_EOL;
if (ArrayHelper::check($this->construct))
{
$script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->construct);
}
// check if custom remove file is set
if ($this->removeFilePaths !== [] && strpos($script, '$this->deleteFiles') === false)
{
// add the default delete files
foreach ($this->removeFilePaths as $filePath)
{
$script .= PHP_EOL . Indent::_(2) . "if (is_file(JPATH_ROOT . '$filePath'))";
$script .= PHP_EOL . Indent::_(2) . "{";
$script .= PHP_EOL . Indent::_(3) . "\$this->deleteFiles[] = '$filePath';";
$script .= PHP_EOL . Indent::_(2) . "}";
}
}
// check if custom remove file is set
if ($this->removeFolderPaths !== [] && strpos($script, '$this->deleteFolders') === false)
{
// add the default delete folders
foreach ($this->removeFolderPaths as $folderPath)
{
$script .= PHP_EOL . Indent::_(2) . "if (is_dir(JPATH_ROOT . '$folderPath'))";
$script .= PHP_EOL . Indent::_(2) . "{";
$script .= PHP_EOL . Indent::_(3) . "\$this->deleteFolders[] = '$folderPath';";
$script .= PHP_EOL . Indent::_(2) . "}";
}
}
// close the function
$script .= PHP_EOL . Indent::_(1) . '}';
// add remove files
$this->preflightBucket['bottom'][] = Indent::_(2) . '//' . Line::_(__Line__, __Class__)
.' remove old files and folders';
$this->preflightBucket['bottom'][] = Indent::_(2) . '$this->removeFiles();';
return $script;
}
@ -266,7 +354,7 @@
$script .= PHP_EOL . Indent::_(1) . " * Called on $name";
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @return boolean True on success';
@ -296,12 +384,6 @@
*/
protected function flight(string $name): string
{
// return empty string if not set
if (empty($this->{$name . 'Active'}))
{
return '';
}
// the pre/post function types
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1)
@ -310,7 +392,7 @@
$script .= PHP_EOL . Indent::_(1)
. ' * @param string $route Which action is happening (install|uninstall|discover_install|update)';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @return boolean True on success';
@ -319,9 +401,9 @@
. $name . '($route, $adapter)';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
. ' get application';
. ' set application to local method var, just use $this->app in future [we will drop $app in J6]';
$script .= PHP_EOL . Indent::_(2)
. '$app = Factory::getApplication();' . PHP_EOL;
. '$app = $this->app;' . PHP_EOL;
// add the default version check (TODO) must make this dynamic
if ('preflight' === $name)
@ -329,36 +411,87 @@
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
.' the default for both install and update';
$script .= PHP_EOL . Indent::_(2)
. '$jversion = new JVersion();';
. '$jversion = new Version();';
$script .= PHP_EOL . Indent::_(2)
. "if (!\$jversion->isCompatible('3.8.0'))";
. "if (!\$jversion->isCompatible('5.0.0'))";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3)
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 3.8.0 before continuing!', 'error');";
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 5.0.0 before continuing!', 'error');";
$script .= PHP_EOL . Indent::_(3) . 'return false;';
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
}
// now add the scripts
foreach ($this->{$name . 'Bucket'} as $route => $_script)
if (!empty($this->{$name . 'Active'}))
{
if (ArrayHelper::check($_script))
// now add the scripts
foreach ($this->{$name . 'Bucket'} as $route => $_script)
{
// set the if and script
$script .= PHP_EOL . Indent::_(2) . "if ('" . $route
. "' === \$route)";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . implode(
PHP_EOL . PHP_EOL, $_script
);
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
if (ArrayHelper::check($_script) && $route !== 'bottom')
{
// set the if and script
$script .= PHP_EOL . Indent::_(2) . "if ('" . $route
. "' === \$route)";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . implode(
PHP_EOL . PHP_EOL, $_script
);
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
}
}
}
if (isset($this->{$name . 'Bucket'}['bottom']) && ArrayHelper::check($this->{$name . 'Bucket'}['bottom']))
{
$script .= PHP_EOL . implode(
PHP_EOL , $this->{$name . 'Bucket'}['bottom']
) . PHP_EOL;
}
// return true
$script .= PHP_EOL . Indent::_(2) . 'return true;';
// close the function
$script .= PHP_EOL . Indent::_(1) . '}';
return $script;
}
/**
* build remove files methods
*
* @return string
* @since 5.0.2
*/
protected function removeFiles(): string
{
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' * Remove the files and folders in the given array from';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @return void';
$script .= PHP_EOL . Indent::_(1) . ' * @since 5.0.2';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected function removeFiles()';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . Indent::_(2) . 'if (!empty($this->deleteFiles))';
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3) . 'foreach ($this->deleteFiles as $file)';
$script .= PHP_EOL . Indent::_(3) . '{';
$script .= PHP_EOL . Indent::_(4) . 'if (is_file(JPATH_ROOT . $file) && !File::delete(JPATH_ROOT . $file))';
$script .= PHP_EOL . Indent::_(4) . '{';
$script .= PHP_EOL . Indent::_(5) . 'echo Text::sprintf(\'JLIB_INSTALLER_ERROR_FILE_FOLDER\', $file) . \'<br>\';';
$script .= PHP_EOL . Indent::_(4) . '}';
$script .= PHP_EOL . Indent::_(3) . '}';
$script .= PHP_EOL . Indent::_(2) . '}';
$script .= PHP_EOL . PHP_EOL . Indent::_(2) . 'if (!empty($this->deleteFolders))';
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3) . 'foreach ($this->deleteFolders as $folder)';
$script .= PHP_EOL . Indent::_(3) . '{';
$script .= PHP_EOL . Indent::_(4) . 'if (is_dir(JPATH_ROOT . $folder) && !Folder::delete(JPATH_ROOT . $folder))';
$script .= PHP_EOL . Indent::_(4) . '{';
$script .= PHP_EOL . Indent::_(5) . 'echo Text::sprintf(\'JLIB_INSTALLER_ERROR_FILE_FOLDER\', $folder) . \'<br>\';';
$script .= PHP_EOL . Indent::_(4) . '}';
$script .= PHP_EOL . Indent::_(3) . '}';
$script .= PHP_EOL . Indent::_(2) . '}';
$script .= PHP_EOL . Indent::_(1) . '}';
return $script;
}

View File

@ -35,6 +35,7 @@ class Injector #Gold {
# shouldAddTraitStatement(object $power) : bool
# handleTraitLogic(string $name, object $power, ...) : void
# addUseStatement(string $name, string $className, ...) : void
# countPartsInString(string $string) : int
# addUseStatements(string $code, ?array $useStatements) : string
# addLines(string $code, string $lines) : string
# addLinesAfterDefinedLine(string $code, string $lines) : string
@ -173,21 +174,28 @@ note left of Injector::addUseStatement
string $namespaceStatement
end note
note right of Injector::addUseStatements
note right of Injector::countPartsInString
Counts the number of parts in a string separated by backslashes.
since: 5.0.2
return: int
end note
note left of Injector::addUseStatements
Insert a line before the class declaration in the given class code.
since: 3.2.0
return: string
end note
note left of Injector::addLines
note right of Injector::addLines
Insert a line before the class declaration in the given class code.
since: 3.2.0
return: string
end note
note right of Injector::addLinesAfterDefinedLine
note left of Injector::addLinesAfterDefinedLine
Inserts a new line after the defined('_JEXEC') line.
since: 3.2.0

View File

@ -16,6 +16,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PowerInterface as Power;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Power\ExtractorInterface as Extractor;
use VDM\Joomla\Componentbuilder\Power\Parser;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Power\InjectorInterface;
@ -476,6 +477,12 @@ class Injector implements InjectorInterface
*/
protected function addUseStatement(string &$name, string $className, string $namespaceStatement): void
{
// we don't add use statements with just one part
if ($this->countPartsInString($namespaceStatement) <= 1)
{
return; // we just update the code
}
if ($name !== $className)
{
$statement = 'use ' . $namespaceStatement . ' as ' . $name . ';';
@ -488,6 +495,27 @@ class Injector implements InjectorInterface
$this->useStatements[$name] = $statement;
}
/**
* Counts the number of parts in a string separated by backslashes.
*
* @param string $string The input string to be evaluated.
*
* @return int The number of parts separated by backslashes.
* @since 5.0.2
*/
protected function countPartsInString(string $string): int
{
// Split the string by the backslash
$parts = explode('\\', $string);
// Count the number of parts and return the result
if (($number = ArrayHelper::check($parts, true)) !== false)
{
return $number;
}
return 0;
}
/**
* Insert a line before the class declaration in the given class code.
*

Some files were not shown because too many files have changed in this diff Show More