From b1bc423a4d6f66bc5d9626f8b4434e2d54d1e23f Mon Sep 17 00:00:00 2001 From: Shader Date: Mon, 23 Oct 2017 09:27:09 +0300 Subject: [PATCH] Plugin documentation --- .gitignore | 1 + docs/assets/plugin-skeleton1.png | Bin 0 -> 55573 bytes docs/assets/plugin-skeleton2.png | Bin 0 -> 20644 bytes docs/assets/plugin-skeleton3.png | Bin 0 -> 4561 bytes docs/assets/plugin-skeleton4.png | Bin 0 -> 4260 bytes docs/assets/plugin-structure.png | Bin 0 -> 8461 bytes docs/developers-guide/plugins.md | 504 ++++++++++++++++++++++++++++++- docs/index.md | 52 +++- 8 files changed, 544 insertions(+), 13 deletions(-) create mode 100644 .gitignore create mode 100644 docs/assets/plugin-skeleton1.png create mode 100644 docs/assets/plugin-skeleton2.png create mode 100644 docs/assets/plugin-skeleton3.png create mode 100644 docs/assets/plugin-skeleton4.png create mode 100644 docs/assets/plugin-structure.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aba02a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/docs/assets/plugin-skeleton1.png b/docs/assets/plugin-skeleton1.png new file mode 100644 index 0000000000000000000000000000000000000000..056a74879dc39cdae3038f69dbe80620021fcf73 GIT binary patch literal 55573 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 literal 0 HcmV?d00001 diff --git a/docs/assets/plugin-skeleton2.png b/docs/assets/plugin-skeleton2.png new file mode 100644 index 0000000000000000000000000000000000000000..3914a0461de17b89fe091a2b0cd5e5728f1db363 GIT binary patch literal 20644 zcmd>lXIPU^ltppv*>bSoIXyJZ zy#WB8=0AUj;>CFc0f6UXC17fL+B6pn@(QkvpWBy*1;i9+~Iq+ zt&`gbx9OuYKvfUQa-74)z=vbcFfc;b+Wle5ceyyXEYLto%;P&T+C}G5YCe_T2|;}g zGQ5iJFlKbgtamDU?-LXqyXgcve7qsDGcB22CgV+Dq|YTMtIT9RVoRp}LCEFckBC>^ zN3+NG=GW!i!vMe~uM_M60{#|yc>7OP*#Cc3bJ6d4fL2E>t9G(Gs)ECWt5iJ(S-9o) z5R6^GyjhXr+*l^}@x^NCS2#LrRZeLz^68JE7To+AWlf$bWIYj_D(MkctLcYE-`t|L z;6-|+;8o`O2m1j_0gQ81jr8T=Gs4n42qoWnt=*j@Ev0Qx>%!Id$A_H(fJ`-NLc)L= z*sU*P$wO61WF)t%>CNZy0=t6r>gCkkV9I0I{wTziF?s_GCh?#6)_SOZyg?sqnOaFj z)!^3ZIFY-=meJCRpL!aVK2CEVTX0llZCXYi0N@irU!WiKKb4~(41gQI^1JkcA3z4n z)-RL&7mTdE@jnBl|I*fpyik0Zk|XCi^?3P308;z7Xx15^b>O3r0I!KGIeI}n0hlUx3mC&&*)Tw7AsbMHr0R>f`rQEY*`5FOZCgiposc@4YnD# zdM7{YR8FRARAw!lR;gSI+8x3+P*kY&!4!>@%HLmuDko!3a&Prh1-of)YpN{vWF?Sa zSI2I!Hfns~%7+0stHh53eW$O!DzRhuGO%b!Uq4;J_ERK~ZnmwsaYi_bN~$<8Yz*p( zOguGM0P$CMP3-I|P`hWAOpq78yK{ASqxiZ7jA^_(e~CHs7K}Skqvu&(1iXRg>pY^` z+TmTFDd)}hQYKKFy81ySa@PwM(mXY4yR#MMdvYfB6X5jYM%;ah-phUOw0_Eb?0>Bh z(O`h>+|OOt?tTka>x&}xrkn(*hxApESz$1%j5Lop;kKNPMp%7Hor95BjtSLH1NVNO zdp|hCq?r#HSv&uf?9;UBd&lp+SXWP;XzA5a^k!pl^QT6(3N+47c^mK&cRZ)hh8HUO zGLF~o>KCPD29sWFt1-X9R}g3?YOcPM+mq1SV|X*zt3D$b1-QLX#=lKc^ezK+?+2I7 zTC198TyRa?T-8P>Kr!bJ_RJk!cseC=UQv>As}}?=Gtv??p`jnIT&PTB|Hb zf+EAK%W}_KC6$=9Q4DYJPnXOHPQR^2m!eH0l_BMl8CWy516YveU!WpII78B6G5v5E zc0r`TZGS6}f?I76iwm?n>djR;Xra99rJH`%s&V};-dj_+1YtK~c)yt#nvYxwE z>+_2j#-vEjzAEi%R=JVcgdG9PNjo=tzHHrAyEB4|J8>OEO% zDjp?-)ce+432NCT;HA$Ki{HoKMY@)v<|qzR_)~r>XcT7VLNLf2sF64*>DfLDL7Sp7 z_MIyB&wRUcaNielXzQ0r)e;wK!ZvbFUDz7)t*x;4%KUI4w{K%`?Qx7Cpr;lZpb0fV zwze3$_$P)imB6D@+zDSU7OZ=*`aBP}yek9^2}g0Dltu1qQgZ4^LdNM9$OlK3)(MHD zgbW*Wq3KxO7yig)>mtZL4ZGnnN!_^mtSCK*l-qk7%M~=uI4c7H1yxUm8)EV#A^rOp@>=+!;_ z@m64egtj4iuywIst@^%W08nA9B-PzYr1t8M7j}(VOh`s?b47qIcANXNUv;9>z!U5@ zI<9>um`NJk*MGmXB_@o2Pv{-1ohwrEq@Y;c;{`RK`bYXZf^iE{wIv9?<+bh|;)K%1 z{5yST_r+WV&Y3++5De1L=mz(R8 zekVmjaWp-(Or<85T?Fo6BKCcXwEEBPny2B7GS)eZZ)*<9T6XtyE_c=AVJ33KWA9Qt zjV^ryGm=g4k<-&Yy%7p|+}~PX6a+sApM~G{-LLj_>&HB_9K?>7D-VMj#F;%6E*QJ#Qagku zxxIh09)EvVXBS&+8q3?`ObmXM7+IPVsHGM({{radGyfHYijr9VrVrCHMI_W*!h=>I zyM0b-Yfm4oOy#ZY-X+~7jvNDeO z(GZ*ojdi5$XpxjXBum6&R1V1~77YgV<21@AdMAfH?c{EB9QHftRx7Lw{`+H6Z`nIG!*^( zSy@r5xBm|RSP(7{7&UlHbjJ~x))Z~GDFRGFK1vO7UEZYqk~51?R1pd0y^o%F9oDb7 z(0mdYH(t8lh+HlS*5p;`%bj?w*mA>R#czQ16cG!|gF&6;{6xqpO zl!$cqB?(~2fHw_UsSlBShL39ZEUU8G!oMj|-6ArQ>aoe#ou^gJ3#`$}$$N=>0|LTtnR!XHkA zFAW!heeagzf`J;yjcY)&Xf+pnc-av{h%zgulA;w*96|ox!Pu-cti6{%ZxC^_V^t-l z7tXTBR|FQXhFJvvG?m@tJ2-uRx#BsgQpKcDW8uA6UV2%|P_^OaY2Zz;DQVsJ?i1-h z7D>>@Qj>dW4MNWJe=1z$UEkzUyL}UWW2Q_%Xw>R;eNc2{+50}wAYE!E;>c?4k(odn zO4}oZ;?-<>NTzCT;(nd8r8UK8CfMBL)(w+$mTSuKY2a^|S@_%*yJ>JZcK z%hms4{G??BiF3lC5Fxb*XmWPKjtb`F_LzucH*-A4E^N5z?vY~)h_d{F#7(c(gaKtN zdql2KkS6!S8n5qWhKl^$-?!@-4wsB(v)oGgoco9CE#JDmRX!ytEb^^izRI4i6IC;b zagbAR^dAFSml=k=NQy)R&bM|Kc}>kB?gl2Bl(_Z{VPK<)XEcwyJZE@txZgESQkdwo z^u4S0$j5EgTMPhTJy-ZR;AXuaGL+L;-t`R+*Usp?nnPXrX=h5EyPnk|_Hwv%#~DyR zenPiVL3f7>_F?Rbc&u~*&8}>y^hjW^&dR$=)Ib->{EatCAG=?QkAmt()>E9>7O)nT zgrtS+zMAS{9_Q(czC5n-w7`nRP4*&24erqJ8%6Q`XPG*cp-Ovqg&mHsS6BwU)179c zXtd=c!I4se+FkJ?^+_w*c4B!ZRo^RX& zeSqH5X82<%R1ksj{Z6{t1PIMckD6!>nHQU*qFO;kj55$dR+tGjXks_P0VHicmoEKq zS+2HZT9=if;QjlI9<0r-v9b|qYWDy)uxD}G!UMPi~zOJ{Me#9=hVmdc<#<9 z20SrZ82DNiq@yhn=wyz77oYkCJ%f13@Ca-m$60AkEu^(cBWBR(x~^euiBZOrV~Xox|e(%g!NVU z{dt88F8^G*1jwAAZbegbjamc^yGk7Pi*Gbu+^qJNm0Ye>L=;A)&lU_E8Qoh+5!$Ek zn3M!vgP+@c;TUYRnmT&a@`$&&P1q244?6iO@vd!2#gauMW81g-FFT*Wx^8PJ)}o_g zrGu~2dP&9*Uc9?MS1VQ)3b*@>%~aadNntGPWGD=KPPoBjHXzpLv%|15MpH{D9_3XT z*0nITn9}XH==o_owciPlHOd4rc8jrBpPP7?_%}kDez@TA2$V7NP!H>}@tlj>ojmv6{NqE;-gj~$#U~*U-XTY+ zq`zDdDy0;6n1bs~YEOT7V;*zbPmowZ;2r0JzPSOPl_}%W{E zgIssVtFZH1-21&RvU~N^d21d?05V1A-$thlQx2HSWvuC@Xo2?{b)Oo` z_u0Mr8OWmU0Wh}lV%G#6DuH&Pd!@~X0{m_X4SQN{A=^|ga;qj=Fp{Wsmmmi_t zm31{LOlMw|dW7vUP_b0V<$W=KUN=h=+NMlX(17QeV@C$Khlp-?BKRsq*C(!Fg%bYA zQcVVEEQS~KBHPg;C7j_md@5<%+#q5L@hG)*GhsZipT}X1*f^i(!(7W~%q)`p%AzWXocJnsaeQ2sOTcr&12j?J?2FswY}|kNWvjN&$h5vk8N1^%cAojpPB?xoZPG3 z`d!b_j#$ybcNKHgxhAQS)BVupD70sTg(28F_^V`;lq@Sai0Irj$hEPq@)k1s_Pr6D zikIC(^a)C-peGJ$ben+7r<4~?k{R!d;pXD^2ah8hN&R3hcD%1Y#HgOI3+4d6gV- z1h6$qj^62dtRhsYpG4vbL^U#Ypj z`dovk8E}2Bx4t|$itg@_XgoF4q|SYtQ6d@*HYw|j!aeS^A~IIWNDxrJAB4Y4ms z5A+QiJp!zIy&@*(H-hcoyEVG^2Sq4sXzIAUN^Ep&-f6EqBJy78L?U6*)7K~>a0CV#?4Fi_*& zp#tl?<*^lK?uc{rH#QTs#<~sxx|U#diQXRliA;M1VwWEJ#Cllm+h*t_ zva}sGXo60cvS#rW2t0#~BAN>k={;hI>&Q__RH9>p;D|`QT}({WW-2 z!TUK2Ak)5e${zQ-;uF(;dFTeD(ao9j=)f6nRJAr1t;hfT5P)UO8_M<%Li&~NHI$#w zy{Zv06t5%Fi=%MKvg!VZNJj2&Tg4XZbiVTQA-aZ7 z6J1wM?_=xvGLI$F78kfG_kN2~Q-%wVjhyOP(c;>e?56j=TW~B2UO8R1V(HcVGCnFj zyJmau8L#B8EUOxUl|#A>&Q&7&y-T~JalN-i@0pe9dYlrHZ8l%#aQ|y>Wb``D%V+e$ zuol5L!#l5`Vpp0qdJ9i10A==49?8CbeyLKREXYr?~iK8aaCoV=H@Ai z(sXl_#}}=oT(_Xnnd?3-3x9DaOe`Ms8H&qMT(L9_Ui46-zJSPm4V=ue`O1qrmAefP z+U<4t2_f%W%VDWV=x0NTX+7Xo`RQP}qZmNXlsaOwg|>!87c zW-6su0XpUqJu+d48j|QBE_}UiiX{1Q0WS6N+;aC*V~5du0#t@#{^Sr|Kh$JL+|_6P zGB^YP{H6H8h+X!W=khuB$Ja;ytyN35B_$=kCt3zXX;l@ZF;VK5Z9%|>$P=!@67hUw zcJ`HNJ9unzk=DB1&xND~!>Vjha8#vB%fQJll9NXGm16kMjnLiY&w&v*g1h$`4HzUu z$&sP8&-pLeP6ET1r80*D^J_!!Cw1i-ACfgz_^qd;>Y9f}N7+ZFzf{hb*__kW zF|!&<7z&P*$V?SpJPAw?t=rhp;gy`Q#oNh?)a`Hd^QOahHwn?O*+9p=KFaZW^DZAI zE`li5nRqY#yCpqu|0H?yII&`Sa!uz*zc4TXlu|kFMmZT&ub`sp?%z?T`uwF|^2LtV ziKqP^;O<>RT{U;aUVVPxoIoMaqUI_>4DtggEAnz~wT3il8qNSC?Z#-U+ibC!2#?C^ zq-iE7hd5#{YYo|5F9l;z)1-?Sk#&m$f9_O;0Gxt|@0dO6{p%)J+%hg^PT$6F&1WvT zm?=}dXxq`@7uZ1I4uX{rEYR2XR*N&F+Uo2%3TmLSp5%0YR-Sm!ii`|-JN@T@(5mTT zg5uru6~sbG&dT(4s30HhrWs+zJ~{g}5c7sUcvYg%7|Mm1C`fPTB%lWpmRu^PFB(f4 zd3*0cIa7vet)�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 E0`uVUt^fc4 literal 0 HcmV?d00001 diff --git a/docs/assets/plugin-skeleton3.png b/docs/assets/plugin-skeleton3.png new file mode 100644 index 0000000000000000000000000000000000000000..8618c721933c730e16b4449ad7fcfc356e468235 GIT binary patch literal 4561 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 literal 0 HcmV?d00001 diff --git a/docs/assets/plugin-structure.png b/docs/assets/plugin-structure.png new file mode 100644 index 0000000000000000000000000000000000000000..0159c54ce772551a1ab3607a9533f27a8fe03fff GIT binary patch literal 8461 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 literal 0 HcmV?d00001 diff --git a/docs/developers-guide/plugins.md b/docs/developers-guide/plugins.md index 90a1d60..560c7f3 100644 --- a/docs/developers-guide/plugins.md +++ b/docs/developers-guide/plugins.md @@ -1 +1,503 @@ -... \ No newline at end of file +# Introduction + +This guide is meant for users who want to help extend cBackup functionality. Our team created flexible plugin management system which allows users to add their own functionality to cBackup. Plugins in cBackup are represented by module `plugins` sub-modules. This approach ensures that developer has access to any existing cBackup functionality. + +# Plugin structure + +Functioning plugin relies on Yii2 module concept, therefore must be located in "modules/plugins" directory. When the development process comes to release stage, you want to export it as zip-archive. Zip archive filename must be equal to plugin directory name where every word is separated by underscore. E.g. plugin `geomapping` should be distributed in `geo_mapping.zip` file. + +![Sample plugin structure](assets/plugin-structure.png) + +Sample `geomapping` plugin directory structure is provided above. As you can see plugin is basically default Yii2 module except for some changes. Plugin root folder must contain json file with the same name as plugin directory. Every word in json filename must be separated with underscore, e.g. `geo_mapping.json` + +Plugin base file name must be equal to plugin root directory name converted to camel case, e.g. `GeoMapping.php`. All database altering must be located in `sql` directory. Third party extensions if needed must be placed in directory `libraries`. + +# Plugin JSON file structure + +Plugin json consists from two parts: metadata and form description. Metadata is the information about plugin which is saved in `plugin` table in cBackup database upon the installation. Here is metadata example: + +```json +{ + "metadata": { + "name": "geo_mapping", + "author": "cBackup Team", + "copyright": "Copyright (C) 2017 cBackup Team. All rights reserved.", + "license": "GNU Affero General Public License (AGPLv3)", + "authorName": "Imants Cernovs", + "authorEmail": "cernovs.imants@gmail.com", + "authorUrl": "www.cbackup.me", + "version": "1.0.0", + "compatibility": "0.0.1", + "description": "Plugin for node geolocation via Google Maps", + "widget": "node" + } +} +``` + +Mandatory fields are: +* **name**: plugin name, must be the same as plugin .zip filename. E.g. if your plugin is distributed in `geo_mapping.zip`, then `name` parameter must be `geo_mapping`, otherwise installation will fail; +* **author**: person or organization who created plugin; +* **version**: plugin version. We use [Semantic Versioning](http://semver.org/) for cBackup and recommend stick with it in plugins; +* **compatibility**: minimal cBackup version suitable for your plugin; +* **description**: brief plugin description + +If your plugin has a widget, you can set extra parameter `"widget": "node"`, and your widget will be rendered in node view. For now, we support only node widgets. In the upcoming releases we are going to add more binding points for plugins. + +## Plugin form + +If your plugin needs some dynamic settings to be adjusted by user, you can specify them in plugin form. Later this form will be rendered in plugin management view. Here is form object in plugin JSON file where settings are split by tabs: + +```json +{ + "form" : { + "tabName1": { + "fields" : [] + }, + "tabName2": { + "fields" : [] + }, + "tabName3": { + "fields" : [] + } + } +} +``` + +### Text input + +```json +{ + "type": "textInput", + "label": "Test Input", + "name": "test_1_input", + "default": "123", + "description": "Add some description if needed", + "options": { + "class": "form-control", + "required": true, + "pattern": "[0-9]*", + "minlength": "3" + } +} +``` + +The JSON above will render simple text input. Where `"options"` are any valid text input tag HTML attributes. See [documentation](https://www.w3schools.com/tags/tag_input.asp) for more information. + +### Drop down select + +```json +{ + "type": "dropDownList", + "label": "Test dropdownlist", + "name": "test_2_input", + "default": "0", + "description": "Add some description if needed", + "options": { + "class": "select2" + }, + "values": { + "0": "Option 1", + "1": "Option 2" + } +} +``` + +You can set input type by configuring "type" attribute, by default text attribute is set. But the code above will render dropdown select input. If you configure parameter as "select2", the dynamic Select2 dropdown will be rendered. Values can be translated if you add translation in plugin `general.php` file. In the same way as for text input, `options` [any valid html select attributes](https://www.w3schools.com/tags/tag_select.asp). + +### Bootstrap toggle + +```json +{ + "type": "toggle", + "label": "Test checkbox toggle", + "name": "test_3_input", + "default": "0", + "description": "Add some description if needed", + "toggle": { + "data-on": "Yes", + "data-off": "No" + }, + "options": { + "data-onstyle": "success", + "data-offstyle": "danger", + "uncheck": "0" + } +} +``` + +The code above will render Bootstrap Toggle input. Please see [plugin documentation](http://www.bootstraptoggle.com/) for valid `options`. All plugin parameters can be passed via `options`. Please consider setting toggle text like in example above, otherwise text will not be translated. + +### iCheck (checkbox) + +```json +{ + "type": "checkbox", + "label": "Test checkbox iCheck", + "name": "test_4_input", + "default": "1", + "description": "Add some description if needed", + "options": { + "data-checkbox-class": "icheckbox_minimal-red", + "uncheck": "0" + } +} +``` + +The code above will render iCheck plugin checkbox. Please see [plugin documentation](http://icheck.fronteed.com/) for valid `options`. To change checkbox color you can set iCheck class like in example, if checkbox class is not set green checkbox will be rendered by default. + +### Radio input + +```json +{ + "type": "radioList", + "label": "Test radio list", + "name": "test_5_input", + "default": "0", + "description": "Add some description if needed", + "values": { + "0": "Option 1", + "1": "Option 2", + "2": "Option 2", + "3": "Option 2" + } +} +``` + +The code above will render Bootstrap radio button list. Options can be translated if you add translation in plugin `general.php` file. Valid `options` can be checked in the [official documentation](https://www.w3.org/wiki/HTML/Elements/input/radio) + +### Textarea + +```json +{ + "type": "textarea", + "label": "Test textarea", + "name": "test_6_input", + "default": "This is some textarea", + "description": "Add some description if needed", + "options": { + "class": "form-control", + "style": "resize: vertical;", + "required": true + } +} +``` + +The code above will render text area. Valid `options` can be checked in the [official documentation](https://www.w3schools.com/tags/tag_textarea.asp). + +## Widget configuration + +If your plugin contains widget you must add following tab. The code below will allow user enable or disable plugin widget. You can add extra fields if you need more parameters for your widget. + +```json +{ + "widget": { + "fields" : [ + { + "type": "toggle", + "label": "Enable widget", + "name": "widget_enabled", + "default": "0", + "description": "Add some description if needed", + "toggle": { + "data-on": "Yes", + "data-off": "No" + }, + "options": { + "data-onstyle": "success", + "data-offstyle": "danger", + "uncheck": "0" + } + } + ] + } +} +``` + +# Plugin base file + +Plugin base file is regular Yii2 module base file with some modifications. Let have a look at Geo Mapping plugin base file. + +```php +initPlugin(); + require_once(__DIR__ . '/libraries/vendor/autoload.php'); + + /** Change controller namespace to access commands */ + if (\Yii::$app instanceof Application && $this->params['plugin_enabled'] == 1) { + $this->controllerNamespace = 'app\modules\plugins\geomapping\commands'; + } + + } + +} +``` + +This file can be generated using Yii2 built in scaffolding tool Gii. To add to module all necessary functionality you must register trait from `app\traits\PluginTrait` and to call its' initializing method as `$this->initPlugin()` (see example above). Plugin Geo Mapping is using third party extensions so we must register autoload.php as PSR-4 suggests. + +# Adding plugin tables to database + +To add your custom tables to cBackup you want to create table installation file in plugin `sql` directory. Files' name must be equal to your plugin name with all words are in camel case and must end with word `Tables`. E.g. if your plugin name is `geo_mapping` then table installation file name must be `GeoMappingTables.php` + +```php +command->createTable('{{%plg_geomapping_geolocation}}', [ + 'id' => $this->integer(11)->notNull().' AUTO_INCREMENT', + 'node_id' => $this->integer(11)->notNull(), + 'last_query' => $this->string(255)->notNull(), + 'full_address' => $this->string(255)->notNull(), + 'address_data' => $this->text()->notNull(), + 'latitude' => $this->decimal(10, 8)->notNull(), + 'longitude' => $this->decimal(11, 8)->notNull(), + 'created' => $this->timestamp()->notNull()->defaultExpression('CURRENT_TIMESTAMP'), + 'modified' => $this->timestamp()->defaultValue(null), + 'PRIMARY KEY (`id`)' + ])->execute(); + + + $this->command->addForeignKey('fk_plg_geomapping_geolocation1', '{{%plg_geomapping_geolocation}}', + 'node_id', '{{%node}}', 'id', 'CASCADE', 'CASCADE')->execute(); + + $this->command->createIndex('node_id_UNIQUE', '{{%plg_geomapping_geolocation}}', 'node_id', true) + ->execute(); + + return true; + } + + /** + * @inheritdoc + */ + public function update() + { + return true; + } + + /** + * @inheritdoc + */ + public function remove() + { + $this->command->dropTable('{{%plg_geomapping_geolocation}}')->execute(); + return true; + } + +} +``` + +Table class must extend abstract `PluginTableInstaller` class. All plugin tables must be prepended with `plg_` prefix and table name must contain plugin name. Table name format: `prefix_pluginname_tablename`, for example `plg_geomapping_geolocation`. Database table names have to be singular E.g. `plg_geomapping_geolocation`, ` plg_geomapping_log `. Only many-to-many relation tables can be plural. M2M table should be named e.g. `plg_geomapping_geo_has_nodes`. **We do not allow modify cBackup core tables!** + +# Plugin widgets + +We allow developers implementing widgets which later can be placed in node view page. At this moment, it is only possible to place widgets in node view page. Basically plugin widgets are standard Yii2 widgets with some modifications. You must create two public variables `$node_id` and `$plugin`. In widget `init()` method you must assign `$this->plugin` variable to plugin object using `\Yii::$app->getModule('plugins/yourpluginname');`. The example of the widget is shown below: + +```php +plugin = \Yii::$app->getModule('plugins/geomapping'); + $this->data = Geolocation::find()->where(['node_id' => $this->node_id])->one(); + } + + /** + * Render geo mapping view + * + * @return string + */ + public function run() + { + return $this->render('geo_mapping_widget', [ + 'plugin' => $this->plugin, + 'node_id' => $this->node_id, + 'data' => $this->data, + ]); + } + +} +``` + +# Accessing plugin parameters and translations + +You can access all plugin parameters. Here are some examples how to access plugin parameters from specific location. + +1. Access to plugin parameters from model + 1. all parameters - `Yii::$app->controller->module->params;` + 2. specific parameter - `Yii::$app->controller->module->params[‘key’];` + 3. translations - `Yii::$app->controller->module::t(‘general’, ‘Test’);` +2. Access to plugin parameters from controller + 1. all parameters - `$this->module->params['plugin access'];` + 2. specific parameter - `$this->module->params['plugin access'];` + 3. translations - `$this->module::t('general', ’Test’);` +3. Access to plugin parameters from view + 1. all parameters - `$this->context->module->params['plugin_access'];` + 2. specific parameter - `$this->context->module ->params['plugin_access'];` + 3. translations - `$this->context->module::t('general', ’Test’);` + +# Creating plugin basic structure + +In this example we will create plugin skeleton to better understand plugin creating procedure. So let’s start. We will call our plugin some_example. First we must add entry to plugins table open phpMyAdmin and locate plugins table. See example below. + +![Plugin skeleton 1](assets/plugin-skeleton1.png) + +During the development you can add params and later use them in your code. After you have finished plugin development move all your created params to installation json file. See json creating file example. + +Then we must create plugin skeleton using Yii2 Gii code generator tool `http://localhost/index.php?r=gii` and choose _Module generator_. + +![Plugin skeleton 2](assets/plugin-skeleton2.png) + +1. Plugin name without underscore +2. Plugin name in camel case without underscore + +After generating module run `yii cache/flush-all` from CLI. In your project you must see something like this: + +![Plugin skeleton 3](assets/plugin-skeleton3.png) + +But at this moment plugin is not working correctly if you try to open it you will see exception. We need to modify plugin base file. Let’s open base file and register PluginTrait. Your base file must look something like this: + +```php +initPlugin(); + } +} +``` + +Now our new plugin is working. Let’s add all remaining plugin files and directories: + +![Plugin skeleton 4](assets/plugin-skeleton4.png) + +As you can see we've created `messages` directory with translation for Russian language, and `some_example.json` where plugin metadata and management form information will be stored. Please see this document for detailed explanation about JSON file structure. + +At this point you can start developing plugin as standard Yii2 module. You can access all cBackup method by using namespaces. If your plugin needs custom tables, please see this document on how to create custom plugin tables. To run sql install/remove method create following action in your controller and run this action. + +```php +install() : $sql->remove(); + return $do_action; +} +``` +In your browser run `http://localhost/index.php?r=plugins%2Fsomeexample%2Fdefault/run-sql&action=your_action` and set `action` param to `0` for install or to `1` for delete. After development delete this method. + +If your plugin has tables, you must generate models using Yii2 Gii tool. In model generator tool, set namespace to location where your plugin is located for example `app\modules\plugins\someexample\models`. This will create models in your plugin directory. Also check `Use Table Prefix` checkbox. + +After you have finished creating plugin and created proper installation json file you can create zip file with your plugin name. In this case it will be `some_example.zip`. Before installation delete your plugin via cBackup plugin management user interface. If you need more complicated example, please feel free taking any existing plugins from cBackup bundle as an example and base. diff --git a/docs/index.md b/docs/index.md index a486817..33afd11 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,19 +1,47 @@ # cBackup -... +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.0-8892BF.svg)](https://php.net/) +[![Documentation Status](https://readthedocs.org/projects/cbackup/badge/?version=latest)](http://cbackup.readthedocs.org) +[![Website](https://img.shields.io/website-up-down-green-red/http/shields.io.svg?label=website)](http://cbackup.me) -# System requirements - -... - -# Conceptual terms +cBackup [siː ˈbækʌp] — free open source network equipment configuration backup tool. -... +# Features -# Support request +* Scheduled network devices configuration backups +* Version control for configuration changes tracking +* Flexible configuration via web interface +* Multithreaded highly efficient java daemon +* Standalone privacy abiding deployment -... - -# Issue reporting +# System requirements -... +* Linux server +* Web server +* Java 8, JRE +* MySQL 5.7 or newer (or compatible MariaDB, Percona, etc) +* Git 2.7 or newer +* NetSNMP +* OpenSSH +* libCurl +* PHP 7.0 or newer with necessary modules + * ctype + * curl + * gmp + * intl + * mbstring + * mysqlnd + * openssl + * pcre + * PDO + * pdo_mysql + * Reflection + * snmp + * SPL + * SSH2 + * zip + +# Community and support + +* Issues can be reported to Github directly or via forum +* For support you can check cBackup official website and forum. Currently system is provided in its Early Access stage, feel free to request features and new hardware support.