├── .gitignore
├── CONTRIBUTING.md
├── Gruntfile.js
├── README.md
├── bower.json
├── css
├── app.css
├── bootstrap-responsive.css
├── bootstrap-responsive.min.css
├── bootstrap.css
└── bootstrap.min.css
├── docs
└── en
│ ├── Framework
│ ├── Framework.md
│ ├── Packages
│ │ └── DI.md
│ ├── Recipes.md
│ └── Recipes
│ │ └── Configuration-Service-Provider.md
│ ├── cms
│ ├── cms.md
│ ├── extensions.md
│ ├── platform.md
│ ├── platform
│ │ ├── crypt.md
│ │ ├── data.md
│ │ ├── database.md
│ │ ├── date.md
│ │ ├── facebook.md
│ │ ├── feed.md
│ │ ├── form
│ │ │ ├── field-accesslevel.md
│ │ │ ├── field-cachehandler.md
│ │ │ ├── field-calendar.md
│ │ │ ├── field-captcha.md
│ │ │ ├── field-checkbox.md
│ │ │ ├── field-checkboxes.md
│ │ │ ├── field-chromestyle.md
│ │ │ ├── field-color.md
│ │ │ ├── field-list.md
│ │ │ ├── field-text.md
│ │ │ └── fields.md
│ │ ├── github.md
│ │ ├── google.md
│ │ ├── http.md
│ │ ├── image.md
│ │ ├── input.md
│ │ ├── keychain.md
│ │ ├── layout.md
│ │ ├── linkedin.md
│ │ ├── log.md
│ │ ├── mvc.md
│ │ ├── oauth1.md
│ │ ├── object.md
│ │ ├── openstreetmap.md
│ │ └── profiler.md
│ ├── recipes.md
│ └── recipes
│ │ └── adding-custom-form-parameters-with-a-plugin.md
│ ├── home.md
│ └── menu.md
├── img
├── glyphicons-halflings-white.png
└── glyphicons-halflings.png
├── index-async.html
├── index.html
├── javascripts
└── scale.fix.js
├── js
├── app.js
├── bootstrap.js
├── bootstrap.min.js
├── controllers.js
├── directives.js
├── filters.js
├── lib
│ ├── angular.js
│ ├── angular.min.js
│ ├── angulartics-google-analytics.js
│ └── angulartics.js
├── marked.js
└── services.js
├── package.json
├── params.json
├── partials
└── docPage.html
└── stylesheets
├── pygment_trac.css
└── styles.css
/.gitignore:
--------------------------------------------------------------------------------
1 | .*
2 | build/
3 | node_modules/
4 | CNAME
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Joomla Developer Docs
2 |
3 | See the [wiki](https://github.com/joomla/joomla-developer-docs/wiki) for information on how to contribute and how to help.
4 |
5 | All content must be submitted under the provisions of the [Joomla Electronic Documentation License](http://docs.joomla.org/JEDL) v1.0 or later.
6 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | grunt.initConfig({
4 | concat: {
5 | bootstrap : {
6 | src: [
7 | 'build/bootstrap/js/*.js'
8 | ],
9 | dest: 'js/lib/bootstrap.js'
10 | }
11 | },
12 | copy: {
13 | bootstrap: {
14 | files: [
15 | {expand: true, cwd: 'build/bootstrap/img/', src: ['**'], dest: 'img/'},
16 | {expand: true, cwd: 'build/angular/', src: ['*.js'], dest: 'js/lib'},
17 | {expand: true, cwd: 'build/angulartics/src/', src: ['angulartics.js', 'angulartics-google-analytics.js'], dest: 'js/lib'}
18 | /*{expand: true, cwd: 'build/jquery/', src: ['*.js'], dest: 'js/lib'}*/
19 | ]
20 | }
21 | },
22 | less: {
23 | prod: {
24 | options: {
25 | compress: true,
26 | yuicompress: true
27 | },
28 | files: {
29 | 'tmp/css/styles.min.css': 'tmp/less/build.less'
30 | }
31 | }
32 | },
33 | uglify: {
34 | app: {
35 | options: {
36 | mangle: false
37 | },
38 | files: {
39 | 'js/lib/bootstrap.min.js': 'js/lib/bootstrap.js'
40 | }
41 | }
42 | }
43 | });
44 |
45 | grunt.loadNpmTasks('grunt-contrib');
46 |
47 | grunt.registerTask('default', [ 'copy' ]);
48 | };
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Joomla Developer Documentation
2 |
3 | Experimental library for Joomla developer documentation.
4 |
5 | This is an unofficial library of somewhat official looking developer documentation for software produced by the Joomla project.
6 |
7 | For information on how to contribute, see the [wiki](https://github.com/joomla/joomla-developer-docs/wiki).
8 |
9 | For the published version, see [http://developer.docs.joomla.org/](http://developer.docs.joomla.org/).
10 |
11 | ## Table of Contents
12 |
13 | * [Joomla CMS](http://developer.docs.joomla.org/#/en/cms/cms.md)
14 | * [Joomla Framework](http://developer.docs.joomla.org/#/en/Framework/Framework.md)
15 | * [Joomla Issue Tracker](http://issues.joomla.org)
16 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "JoomlaDevDocs",
3 | "version": "0.0.1",
4 | "dependencies": {
5 | "angular": "1.0.8",
6 | "bootstrap": "2.3.1",
7 | "angulartics" : "*"
8 | },
9 | "devDependencies": {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/css/app.css:
--------------------------------------------------------------------------------
1 | /* app css stylesheet */
2 |
3 | .menu {
4 | list-style: none;
5 | border-bottom: 0.1em solid black;
6 | margin-bottom: 2em;
7 | padding: 0 0 0.5em;
8 | }
9 |
10 | .menu:before {
11 | content: "[";
12 | }
13 |
14 | .menu:after {
15 | content: "]";
16 | }
17 |
18 | .menu > li {
19 | display: inline;
20 | }
21 |
22 | .menu > li:before {
23 | content: "|";
24 | padding-right: 0.3em;
25 | }
26 |
27 | .menu > li:nth-child(1):before {
28 | content: "";
29 | padding: 0;
30 | }
31 |
32 | /* The following is for the Markdown table styling */
33 | table
34 | {
35 | border: 1px solid gray;
36 | }
37 |
38 | td
39 | {
40 | border: 1px solid gray;
41 | padding: 10px;
42 | }
43 |
44 | th
45 | {
46 | border: 1px solid gray;
47 | padding: 10px;
48 | }
49 |
50 | /* The following is for the collapse menu functions */
51 | ul.tree
52 | {
53 | display:none
54 | }
55 |
56 | label.tree-toggler:before
57 | {
58 | content: "+";
59 | padding-right: 5px;
60 | color: green;
61 | font-family: monospace;
62 | font-weight: bold;
63 | font-size: 1.1em;
64 | }
65 |
66 | label.tree-toggler.open:before
67 | {
68 | content: "-";
69 | color: red;
70 | }
71 |
--------------------------------------------------------------------------------
/css/bootstrap-responsive.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Responsive v2.3.1
3 | *
4 | * Copyright 2012 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world @twitter by @mdo and @fat.
9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}
10 |
--------------------------------------------------------------------------------
/docs/en/Framework/Framework.md:
--------------------------------------------------------------------------------
1 | # Developer Documentation for the Joomla Framework
2 |
3 | Landing page.
4 |
--------------------------------------------------------------------------------
/docs/en/Framework/Packages/DI.md:
--------------------------------------------------------------------------------
1 | # The DI Package
2 |
3 | The Dependency Injection package for Joomla provides a simple IoC Container for your application.
4 | Dependency Injection allows you the developer to control the construction and lifecycle of your objects,
5 | rather than leaving that control to the classes themselves. Instead of hard coding a class's dependencies
6 | within the class `__construct()` method, you instead provide to a class the dependencies it requires as
7 | arguments to its constructor. This helps to decrease hard dependencies and to create loosely coupled code.
8 |
9 | Read more about [why you should be using dependency injection](docs/why-dependency-injection.md).
10 |
11 | An Inversion of Control (IoC) Container helps you to manage these dependencies in a controlled fashion.
12 |
13 | ## Using the Container
14 |
15 | ### Creating a Container
16 |
17 | Creating a container usually happens very early in the application lifecycle. For a Joomla MVC app, this
18 | typically happens in the application's `doExecute` method. This allows your application access to the DI
19 | Container, which you can then use within the app class to build your controllers and their dependencies.
20 |
21 | ```php
22 | namespace My\App;
23 |
24 | use Joomla\DI\Container;
25 | use Joomla\Application\AbstractWebApplication;
26 |
27 | class WebApp extends AbstractWebApplication
28 | {
29 | protected $container;
30 |
31 | // ...snip
32 |
33 | protected function doExecute()
34 | {
35 | $this->container = new Container;
36 |
37 | // ...snip
38 | }
39 | }
40 | ```
41 |
42 | Another feature of the container is the ability to create a child container with a different resolution
43 | scope. This allows you to easily override an interface binding for a specific controller, without
44 | destroying the resolution scope for the rest of the classes using the container. A child container will
45 | search recursively through it's parent containers to resolve all the required dependencies.
46 |
47 | ```php
48 | use Joomla\DI\Container;
49 |
50 | $container->set('Some\Interface\I\NeedInterface', new My\App\InterfaceImplementation);
51 | // Application executes... Come to a class that needs a different implementation.
52 | $child = $container->createChild();
53 | $child->set('Some\Interface\I\NeedInterface', new My\Other\InterfaceImplementation);
54 | ```
55 |
56 | ### Setting an Item
57 |
58 | Setting an item within the container is very straightforward. You pass the `set` method a string `$key`
59 | and a `$value`, which can be pretty much anything. If the `$value` is an anonymous function or a `Closure`,
60 | or a callable value,
61 | that value will be set as the resolving callback for the `$key`. If it is anything else (an instantiated
62 | object, array, integer, serialized controller, etc) it will be wrapped in a closure and that closure will
63 | be set as the resolving callback for the `$key`.
64 |
65 | > If the `$value` you are setting is a closure or a callable, it will receive a single function argument,
66 | > the calling container. This allows access to the container within your resolving callback.
67 |
68 | ```php
69 | // Assume a created $container
70 | $container->set('foo', 'bar');
71 |
72 | $container->set('something', new Something);
73 |
74 | $container->set('callMe', array($this, 'callMe');
75 | // etc
76 | ```
77 |
78 | In the case of a callable, the called method must take a `Container` object as its first and only argument.
79 |
80 | When setting items in the container, you are allowed to specify whether the item is supposed to be a
81 | shared or protected item. A shared item means that when you get an item from the container, the resolving
82 | callback will be fired once, and the value will be stored and used on every subsequent request for that
83 | item. The other option, protected, is a special status that you can use to prevent others from overwriting
84 | the item down the line. A good example for this would be a global config that you don't want to be
85 | overwritten. The third option is that you can both share AND protect an item. A good use case for this would
86 | be a database connection that you only want one of, and you don't want it to be overwritten.
87 |
88 | ```php
89 | // Assume a created $container
90 | $container->share(
91 | 'foo',
92 | function ()
93 | {
94 | // some expensive $stuff;
95 |
96 | return $stuff;
97 | }
98 | );
99 |
100 | $container->protect(
101 | 'bar',
102 | function (Container $c)
103 | {
104 | // Don't overwrite my db connection.
105 | $config = $c->get('config');
106 |
107 | $databaseConfig = (array) $config->get('database');
108 |
109 | return new DatabaseDriver($databaseConfig);
110 | }
111 | );
112 | ```
113 |
114 | > Both the `protect` and `share` methods take an optional third parameter. If set to `true`, it will
115 | > tell the container to both protect _and_ share the item. (Or share _and_ protect, depending on
116 | > the origin method you call. Essentially it's the same thing.)
117 |
118 | The most powerful feature of setting an item in the container is the ability to bind an implementation
119 | to an interface. This is useful when using the container to build your app objects. You can typehint
120 | against an interface, and when the object gets built, the container will pass your implementation.
121 |
122 | @TODO
123 | - Interface binding usage example
124 |
125 | ### Item Aliases
126 |
127 | Any item set in the container can be aliased. This allows you to create an object that is a named
128 | dependency for object resolution, but also have a "shortcut" access to the item from the container.
129 |
130 | ```php
131 | // Assume a created $container
132 | $container->set(
133 | 'Really\Long\ConfigClassName',
134 | function ()
135 | {
136 | // ...snip
137 | }
138 | );
139 |
140 | $container->alias('config', 'Really\Long\ConfigClassName');
141 |
142 | $container->get('config'); // Returns the value set on the aliased key.
143 | ```
144 |
145 | ### Getting an Item
146 |
147 | At its most basic level, the DI Container is a registry that holds keys and values. When you set
148 | an item on the container, you can retrieve it by passing the same `$key` to the `get` method that
149 | you did when you set the method in the container.
150 |
151 | > If you've aliased a set item, you can also retrieve it using the alias key.
152 |
153 | ```php
154 | // Assume a created $container
155 | $container->set('foo', 'bar');
156 |
157 | $foo = $container->get('foo');
158 | ```
159 |
160 | Normally, the value you'll be passing will be a closure. When you fetch the item from the container,
161 | the closure is executed, and the result is returned.
162 |
163 | ```php
164 | // Assume a created $container
165 | $container->set(
166 | 'foo',
167 | function ()
168 | {
169 | // Create an instance of \Joomla\Github\Github;
170 |
171 | return $github;
172 | }
173 | );
174 |
175 | $github = $container->get('foo');
176 |
177 | var_dump($github instanceof \Joomla\Github\Github); // prints bool(true)
178 | ```
179 |
180 | If you get the item again, the closure is executed again and the result is returned.
181 |
182 | ```php
183 | // Picking up from the previous codeblock
184 | $github2 = $container->get('foo');
185 |
186 | print($github2 === $github); // prints bool(false)
187 | ```
188 |
189 | However, if you specify that the object as shared when setting it in the container, the closure will
190 | only be executed once (the first time it is requested), the value will be stored and then returned
191 | on every subsequent request.
192 | ```php
193 | // Assume a created $container
194 | $container->share(
195 | 'twitter',
196 | function ()
197 | {
198 | // Create an instance of \Joomla\Twitter\Twitter;
199 |
200 | return $twitter;
201 | }
202 | );
203 |
204 | $twitter = $container->get('twitter');
205 | $twitter2 = $container->get('twitter');
206 |
207 | var_dump($twitter === $twitter2); // prints bool(true)
208 | ```
209 |
210 | If you've specified an item as shared, but you really need a new instance of it for some reason, you
211 | can force the creation of a new instance by passing true as the second argument, or using the `getNewInstance`
212 | convenience method.
213 |
214 | > When you force create a new instance on a shared object, that new instance replaces the instance
215 | > that is stored in the container and will be used on subsequent requests.
216 |
217 | ```php
218 | // Picking up from the previous codeblock
219 | $twitter3 = $container->getNewInstance('twitter');
220 |
221 | var_dump($twitter === $twitter3); // prints bool(false)
222 |
223 | $twitter4 = $container->get('twitter');
224 | var_dump($twitter3 === $twitter4); // prints bool(true)
225 | ```
226 |
227 | > If you've created a child container, you can use the `get` and `getNewInstance` methods on it to
228 | > fetch items from the parent container that have not yet been overwritten in the child container.
229 |
230 |
231 | ### Instantiate an object from the Container
232 |
233 | The most useful function of the container is it's ability to build complete objects, instantiating
234 | any needed dependencies along the way. When you use the container in this way, it looks at a classes
235 | constructor declared dependencies and then automatically passes them into the object.
236 |
237 | > Classes will only receive dependencies that have been properly typehinted or given a default value.
238 |
239 | Since the container allows you to bind an implementation to an interface, this gives you great flexibility
240 | to build your classes within the container. If your model class requires a user repository, you can typehint
241 | against a `UserRepositoryInterface` and then bind an implementation to that interface to be passed into
242 | the model when it's created.
243 |
244 | ```php
245 | class User implements UserRepositoryInterface
246 | {
247 | // ...snip
248 | }
249 |
250 | class UserProfile
251 | {
252 | protected $user;
253 |
254 | public function __construct(UserRepositoryInterface $user)
255 | {
256 | $this->user = $user;
257 | }
258 | }
259 |
260 | // Assume a created $container
261 | $container->set(
262 | 'UserRepositoryInterface',
263 | function ()
264 | {
265 | retur new User;
266 | }
267 | );
268 |
269 | $userProfile = $container->buildObject('UserProfile');
270 |
271 | // Use reflection to get the $user property from $userProfile
272 | var_dump($user instanceof User); // prints bool(true)
273 | var_dump($user instanceof UserRepositoryInterface); // prints bool(true)
274 | ```
275 |
276 | When you build an object, the information required to actually build it (dependencies, etc) are
277 | stored in a callable and set in the container with the class name as the key. You can then fetch
278 | the item from the container by name later on. Alias support applies here as well.
279 |
280 | You can also specify to build a shared object by using the function `buildSharedObject($key)`. This
281 | works exactly as you would expect. The information required to build it is discovered, stored in a
282 | callable, then the callable is executed and the result returned. The result is stored as an instance
283 | within the container and is returned on subsequent requests.
284 |
285 |
286 | ### Extending an Item
287 |
288 | The Container also allows you to extend items. Extending an item can be thought of as a way to
289 | implement the decorator pattern, although it's not really in the strict sense. When you extend an
290 | item, you must pass the key for the item you want to extend, and then a closure as the second
291 | argument. The closure will receive 2 arguments. The first is result of the callable for the given key,
292 | and the second will be the container itself. When extending an item, the new extended version overwrites
293 | the existing item in the container. If you try to extend an item that does not exist, an `\InvalidArgumentException`
294 | will be thrown.
295 |
296 | > When extending an item, normal rules apply. A protected object cannot be overwritten, so you also can not extend them.
297 |
298 | ```php
299 | // Assume a created $container
300 | $container->set('foo', 'bar');
301 |
302 | var_dump($container->get('foo')); // prints string(3) "bar"
303 |
304 | $container->extend(
305 | 'foo',
306 | function ($originalResult, Container $c)
307 | {
308 | return $originalResult .= 'baz';
309 | }
310 | );
311 |
312 | var_dump($container->get('foo')); // prints string(6) "barbaz"
313 | ```
314 |
315 |
316 | ### Service Providers
317 |
318 | Another strong feature of the Container is the ability register a _service provider_ to the container.
319 | Service providers are useful in that they are a simple way to encapsulate setup logic for your objects.
320 | In order to use create a service provider, you must implement the `Joomla\DI\ServiceProviderInterface`.
321 | The `ServiceProviderInterface` tells the container that your object has a `register` method that takes
322 | the container as it's only argument.
323 |
324 | > Registering service providers is typically done very early in the application lifecycle. Usually
325 | > right after the container is created.
326 |
327 | ```php
328 | // Assume a created $container
329 | use Joomla\DI\Container;
330 | use Joomla\DI\ServiceProviderInterface;
331 | use Joomla\Database\DatabaseDriver;
332 |
333 | class DatabaseServiceProvider implements ServiceProviderInterface
334 | {
335 | public function register(Container $container)
336 | {
337 | $container->share(
338 | 'Joomla\Database\DatabaseDriver',
339 | function () use ($container)
340 | {
341 | $databaseConfig = (array) $container->get('config')->get('database');
342 |
343 | return new DatabaseDriver($databaseConfig);
344 | },
345 | true
346 | );
347 |
348 | $container->alias('db', 'Joomla\Database\DatabaseDriver');
349 | }
350 | }
351 |
352 | $container->registerServiceProvider(new DatabaseServiceProvider);
353 | ```
354 |
355 | Here is an alternative using a callable.
356 |
357 | ```php
358 | // Assume a created $container
359 | use Joomla\DI\Container;
360 | use Joomla\DI\ServiceProviderInterface;
361 |
362 | class CallableServiceProvider implements ServiceProviderInterface
363 | {
364 | public function getCallable(Container $c)
365 | {
366 | return 'something';
367 | }
368 |
369 | public function register(Container $container)
370 | {
371 | $container->set('callable', array($this, 'getCallable');
372 | }
373 | }
374 |
375 | $container->registerServiceProvider(new CallableServiceProvider);
376 | ```
377 |
378 | The advantage here is that it is easier to write unit tests for the callable method (closures can be awkward to isolate
379 | and test).
380 |
381 | ### Container Aware Objects
382 |
383 | You are able to make objects _ContainerAware_ by implementing the `Joomla\DI\ContainerAwareInterface` within your
384 | class. This can be useful when used within the construction level of your application. The construction
385 | level is considered to be anything that is responsible for the creation of other objects. When using
386 | the MVC pattern as recommended by Joomla, this can be at the application or controller level. Controllers
387 | in Joomla are responsible for creating Models and Views, and linking them together. In this case, it would
388 | be reasonable for the controllers to have access to the container in order to build these objects.
389 |
390 | > __NOTE:__ The business layer of your app (eg: Models) should _never_ be container aware. Doing so will
391 | > make your code harder to test, and is a far cry from best practices.
392 |
--------------------------------------------------------------------------------
/docs/en/Framework/Recipes.md:
--------------------------------------------------------------------------------
1 | # Recipes for Joomla Framework Developers
2 |
3 | Landing page.
4 |
5 | ## Dependency Injection
6 |
7 | * [A configuration service provider](#/en/Framework/Recipes/Configuration-Service-Provider.md)
8 |
--------------------------------------------------------------------------------
/docs/en/Framework/Recipes/Configuration-Service-Provider.md:
--------------------------------------------------------------------------------
1 | # A Recipe for a Configuration Service Provider
2 |
3 | Following is an example of a configuration service provider that would load a JSON format configuration file from a
4 | specified location.
5 |
6 | ```php
7 | path = $path;
37 | }
38 |
39 | /**
40 | * Gets a configuration object.
41 | *
42 | * @param Container $c A DI container.
43 | *
44 | * @return Registry
45 | *
46 | * @since 2.0
47 | * @throws \LogicException if the configuration file does not exist.
48 | * @throws \UnexpectedValueException if the configuration file could not be parsed.
49 | */
50 | public function getConfig(Container $c)
51 | {
52 | if (!file_exists($this->path))
53 | {
54 | throw new \LogicException('Configuration file does not exist.', 500);
55 | }
56 |
57 | /** @var \Joomla\Input\Input $input */
58 | $input = $c->get('input');
59 |
60 | $json = json_decode(file_get_contents($this->path));
61 |
62 | if (null === $json)
63 | {
64 | throw new \UnexpectedValueException('Configuration file could not be parsed.', 500);
65 | }
66 |
67 | $temp = new Registry($json);
68 | $profile = $input->get('profile');
69 |
70 | if ($temp->get('profiles.' . $profile))
71 | {
72 | $config = new Registry($temp->get('profiles.' . $profile));
73 | }
74 | else
75 | {
76 | $config = new Registry($temp->get('profiles.default'));
77 | }
78 |
79 | // Automatically set the path for `/etc/`.
80 | $config->set('path.etc', dirname($this->path));
81 |
82 | return $config;
83 | }
84 |
85 | /**
86 | * Registers the service provider within a DI container.
87 | *
88 | * @param Container $container The DI container.
89 | *
90 | * @return void
91 | *
92 | * @since 1.0
93 | */
94 | public function register(Container $container)
95 | {
96 | $that = $this;
97 | $container->share(
98 | 'config',
99 | function ($c) use ($that)
100 | {
101 | return $that->getConfig($c);
102 | }
103 | , true
104 | );
105 | }
106 | }
107 | ```
108 |
109 | To implement this, create a container in the application's `initialise` method. This snippet assumes that you
110 | have defined a constant called `ACME_CONFIG`, probably in the entry-point file that instantiates this application,
111 | that points to the location of the configuration file.
112 |
113 | ```php
114 | namespace Acme;
115 |
116 | use Joomla\Application\AbstractApplication;
117 |
118 | class Application extends AbstractApplication
119 | {
120 | /**
121 | * Custom initialisation method.
122 | *
123 | * Called at the end of the AbstractCliApplication::__construct method. This is for developers to inject
124 | * initialisation code for their application classes.
125 | *
126 | * @return void
127 | *
128 | * @codeCoverageIgnore
129 | * @since 1.0
130 | */
131 | protected function initialise()
132 | {
133 | // New DI stuff!
134 | $container = new Container;
135 |
136 | $container->registerServiceProvider(new Providers\ConfigServiceProvider(ACME_CONFIG));
137 |
138 | $this->container = $container;
139 | }
140 | }
141 | ```
142 |
143 |
--------------------------------------------------------------------------------
/docs/en/cms/cms.md:
--------------------------------------------------------------------------------
1 | # Developer Documentation for the Joomla CMS
2 |
3 | Landing page.
4 |
--------------------------------------------------------------------------------
/docs/en/cms/extensions.md:
--------------------------------------------------------------------------------
1 | # Joomla Extensions
2 |
3 | The Joomla CMS support seven types of extensions.
4 |
5 | ## Components
6 |
7 | A component is used to display and manage data on the web Joomla web site. It main vehicle by which data is viewed
8 | and maintained. An user interactions (a web request) is always handled by a component.
9 |
10 | Components can be installed in either the front-end site application, and/or the backend administrator application.
11 |
12 | ## Modules
13 |
14 | A module is used only used to display data or inject behaviours (such as JavaScript) into a part of the web page.
15 | A module may display web page elements that allow user interaction, such as a login form, but the module code itself
16 | should never process requests. They should be treated as read-only constructs.
17 |
18 | Modules display in fixed positions within a template and can be configured to on different pages of the web site based
19 | on the navigation menu.
20 |
21 | Like components, modules can be installed in either the site and/or administrator applications.
22 |
23 | ## Plugins
24 |
25 | A plugin is used to modify data, presentation or behaviour behind the scenes and does not interact directly with the user.
26 | Rather, plugins use an Observer design pattern to react to events triggered by the CMS application's dispatcher,
27 | and they fall into a number of sub-types:
28 |
29 | * Authentication
30 | * Captcha
31 | * Content
32 | * Editors
33 | * Editors-xtd
34 | * Extension
35 | * Finder
36 | * Quickicon
37 | * Search
38 | * System
39 | * Two Factor Authentication
40 | * User
41 |
42 | Plugins are shared across both the site and administrator applications.
43 |
44 | ## Templates
45 |
46 | A template is the outer presentational framework and structure around which components and modules are displayed.
47 | It defines the look and feel for the web site as a whole.
48 |
49 | Templates can be installed in either the site and/or administrator applications.
50 |
51 | ## Language Packs
52 |
53 | A language pack is a collection of text files in `ini` format that allows static text on the Joomla web site to be
54 | translated into other languages.
55 |
56 | ## Libraries
57 |
58 | A library is base-level code that can be installed to support other types of extensions (for example, a mailing list library).
59 |
60 | Libraries are shared across both the site and administrator applications.
61 |
62 | ## Packages
63 |
64 | A package is simply a collection of extensions that can be installed in a single operation.
65 |
--------------------------------------------------------------------------------
/docs/en/cms/platform.md:
--------------------------------------------------------------------------------
1 | # Joomla CMS Core Platform
2 |
3 | ## Platform Version
4 |
5 | Platform version information can be found by accessing the `JPlatform`
6 | class.
7 |
8 | ### JPlatform
9 |
10 | `JPlatform` is a final class that cannot be modified by the developer. It
11 | has a number of public constant pertaining to the platform version and
12 | some static utility methods.
13 |
14 | #### Constants
15 |
16 | Name | Description
17 | ------------------------------ | ---------------------------
18 | JPlatform::PRODUCT | Joomla Platform
19 | JPlatform::RELEASE | The release number of the platform.
20 | JPlatform::MAINTENANCE | The point maintenance version if applicable.
21 | JPlatform::STATUS | The development status.
22 | JPlatform::BUILD | The build number for the platform, if applicable.
23 | JPlatform::CODE\_NAME | A human readable code name for this version.
24 | JPlatform::RELEASE\_DATE | The official release date for this version.
25 | JPlatform::RELEASE\_TIME | The official release time for this version, if applicable.
26 | JPlatform::RELEASE\_TIME\_ZONE | The timezone for the official release date and time.
27 | JPlatform::COPYRIGHT | The copyright statement.
28 | JPlatform::LINK\_TEXT | An HTML hyperlink to the Joomla Project.
29 |
30 | #### Methods
31 |
32 | `JPlatform` has three utility methods, one for testing the version and two
33 | for display.
34 |
35 | Method | Description
36 | --------------------------------- | ------------------------
37 | JPlatform::isCompatible($version) | Tests if $version is the installed version of the platform.
38 | JPlatform::getShortVersion() | A short textual representation of the platform version.
39 | JPlatform::getLongVersion() | A really verbose representation of the platform version.
40 |
41 | ```php
42 | // Tests the required version of the platform.
43 | if (!JPlatform::isCompatible('11.4'))
44 | {
45 | throw new LogicException(sprintf('Platform version %s not compatible.', JPlatform::getShortVersion());
46 | }
47 | ```
48 |
49 | ## Class Auto-loading
50 |
51 | `JLoader` is the mainstay of the Joomla Platform as it controls auto-loading of classes.
52 |
53 | It removes the need for the developer to include files by hand, or by using a fall to the `jimport` function.
54 |
55 | Multiple ways of auto loading classes, following different conventions are proposed by JLoader.
56 |
57 | ### The Namespace Loader
58 |
59 | Since the release 12.3 of the Joomla Platform there is the possibility to auto classes within namespaces.
60 |
61 | * A developer can register the full path to a top level (root) namespace where the loader can find classes (within this namespace).
62 |
63 | * A developer can override an existing namespace path by replacing it with a new one.
64 |
65 | * A developer can register multiple paths to the same namespace.
66 |
67 | #### Convention
68 |
69 | The convention is to have the namespace names matching the directories names.
70 |
71 | For example :
72 |
73 | ```php
74 |
275 | JLoader::discover('Prefix', '/the/path/');
276 | ```
277 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/crypt.md:
--------------------------------------------------------------------------------
1 | # The Crypt Package
2 |
3 | The Crypt password provides a set of classes that can be used for
4 | encrypting and hashing data.
5 |
6 | ## Interfaces
7 |
8 | ### JCryptPassword
9 |
10 | JCryptPassword is an interface that requires a class to be implemented
11 | with a create and a verify method.
12 |
13 | The create method should take a plain text password and a type and
14 | return a hashed password.
15 |
16 | The verify method should accept a plain text password and a hashed
17 | password and return a boolean indicating whether or not the password
18 | matched the password in the hash.
19 |
20 | The JCryptPassword interface defines the following constants for use
21 | with implementations:
22 |
23 | - `JCryptPassword::BLOWFISH`
24 | - `JCryptPassword::JOOMLA`
25 | - `JCryptPassword::MD5`
26 |
27 | ## Classes
28 |
29 | ### JCryptPasswordSimple
30 |
31 | #### Usage
32 |
33 | In addition to the interface JCryptPassword there is also a basic
34 | implementation provided which provides for use with the most common
35 | password schemes. This if found in the JCryptPasswordSimple class.
36 |
37 | Aside from the two methods create and verify methods, this
38 | implementation also adds an additional method called setCost. This
39 | method is used to set a cost parameter for methods that support workload
40 | factors. It takes an integer cost factor as a parameter.
41 |
42 | JCryptPasswordSimple provides support for bcrypt, MD5 and the
43 | traditional Joomla! CMS hashing scheme. The hash format can be specified
44 | during hash creation by using the constants `JCryptPassword::BLOWFISH`,
45 | `JCryptPassword::MD5` and `JCryptPassword::JOOMLA`. An appropriate salt
46 | will be automatically generated when required.
47 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/data.md:
--------------------------------------------------------------------------------
1 | # The Data Package
2 |
3 | ## JData
4 |
5 | `JData` is a class that is used to store data but allowing you to access the data by mimicking the way PHP handles class properties. Rather than explicitly declaring properties in the class, `JData` stores virtual properties of the class in a private internal array. Concrete properties can still be defined but these are separate from the data.
6 |
7 | ### Construction
8 |
9 | The constructor for a new `JData` object can optionally take an array or an object. The keys of the array or the properties of the object will be bound to the properties of the `JData` object.
10 |
11 | ```php
12 | // Create an empty object.
13 | $object1 = new JData;
14 |
15 | // Create an object with data. You can use an array or another object.
16 | $data = array(
17 | 'foo' => 'bar',
18 | );
19 |
20 | $object2 = new JData($data);
21 |
22 | // The following should echo "bar".
23 | echo $object2->foo;
24 | ```
25 |
26 | ### General Usage
27 |
28 | `JData` includes magic getters and setters to provide access to the internal property store as if they were explicitly declared properties of the class.
29 |
30 | The `bind` method allows for injecting an existing array or object into the `JData` object.
31 |
32 | The `dump` method gets a plain `stdClass` version of the `JData` object's properties. It will also support recursion to a specified number of levels where the default is 3 and a depth of 0 would return a `stdClass` object with all the properties in native form. Note that the `dump` method will only return virtual properties set binding and magic methods. It will not include any concrete properties defined in the class itself.
33 |
34 | The `JsonSerializable` interface is implemented. This method proxies to the `dump` method (defaulting to a recursion depth of 3). Note that this interface only takes effect implicitly in PHP 5.4 so any code built for PHP 5.3 needs to explicitly use either the `jsonSerialize` or the `dump` method before passing to `json_encode`.
35 |
36 | The `JData` class also implements the `IteratorAggregate` interface so it can easily be used in a `foreach` statement.
37 |
38 | ```php
39 | // Create an empty object.
40 | $object = new JData;
41 |
42 | // Set a property.
43 | $object->foo = 'bar';
44 |
45 | // Get a property.
46 | $foo = $object->foo;
47 |
48 | // Binding some new data to the object.
49 | $object->bind(array('goo' => 'car');
50 |
51 | // Get a plain object version of the JData.
52 | $stdClass = $object->dump();
53 |
54 | // Get a property with a default value if it is not already set.
55 | $foo = $object->foo ?: 'The default';
56 |
57 | // Iterate over the properties as if the object were a real array.
58 | foreach ($object as $key => $value)
59 | {
60 | echo "\n$key = $value";
61 | }
62 |
63 | if (version_compare(PHP_VERSION, '5.4') >= 0)
64 | {
65 | // PHP 5.4 is aware of the JsonSerializable interface.
66 | $json = json_encode($object);
67 | }
68 | else
69 | {
70 | // Have to do it the hard way to be compatible with PHP 5.3.
71 | $json = json_encode($object->jsonSerialize());
72 | }
73 | ```
74 |
75 | ## JDataSet
76 |
77 | `JDataSet` is a collection class that allows the developer to operate on a list of `JData` objects as if they were in a typical PHP array (`JDataSet` implements the `ArrayAccess`, `Countable` and `Iterator` interfaces).
78 |
79 | ### Construction
80 |
81 | A typical `JDataSet` object will be instantiated by passing an array of `JData` objects in the constructor.
82 |
83 | ```php
84 | // Create an empty object.
85 | $players = new JDataSet(
86 | array(
87 | new JData(array('race' => 'Elf', 'level' => 1)),
88 | new JData(array('race' => 'Chaos Dwarf', 'level' => 2)),
89 | )
90 | );
91 | ```
92 |
93 | ### General Usage
94 |
95 | Array elements can be manipulated with the `offsetSet` and `offsetUnset` methods, or by using PHP array nomenclature.
96 |
97 | The magic `__get` method in the `JDataSet` class effectively works like a "get column" method. It will return an array of values of the properties for all the objects in the list.
98 |
99 | The magic `__set` method is similar and works like a "set column" method. It will set all a value for a property for all the objects in the list.
100 |
101 | The `clear` method will clear all the objects in the data set.
102 |
103 | The `keys` method will return all of the keys of the objects stored in the set. It works like the `array_keys` function does on an PHP array.
104 |
105 | ```php
106 | // Add a new element to the end of the list.
107 | $players[] => new JData(array('race' => 'Skaven', 'level' => 2));
108 |
109 | // Add a new element with an associative key.
110 | $players['captain'] => new JData(array('race' => 'Human', 'level' => 3));
111 |
112 | // Get a keyed element from the list.
113 | $captain = $players['captain'];
114 |
115 | // Set the value of a property for all objects. Upgrade all players to level 4.
116 | $players->level = 4;
117 |
118 | // Get the value of a property for all object and also the count (get the average level).
119 | $average = $players->level / count($players);
120 |
121 | // Clear all the objects.
122 | $players->clear();
123 | ```
124 |
125 | `JDataSet` supports magic methods that operate on all the objects in the list. Calling an arbitrary method will iterate of the list of objects, checking if each object has a callable method of the name of the method that was invoked. In such a case, the return values are assembled in an array forming the return value of the method invoked on the `JDataSet` object. The keys of the original objects are maintained in the result array.
126 |
127 | ```php
128 | /**
129 | * A custom JData.
130 | *
131 | * @package Joomla\Examples
132 | * @since 12.1
133 | */
134 | class PlayerObject extends JData
135 | {
136 | /**
137 | * Get player damage.
138 | *
139 | * @return integer The amount of damage the player has received.
140 | *
141 | * @since 12.1
142 | */
143 | public function hurt()
144 | {
145 | return (int) $this->maxHealth - $this->actualHealth;
146 | }
147 | }
148 |
149 | $players = new JDataSet(
150 | array(
151 | // Add a normal player.
152 | new PlayerObject(array('race' => 'Chaos Dwarf', 'level' => 2,
153 | 'maxHealth' => 40, 'actualHealth' => '32')),
154 | // Add an invincible player.
155 | new JData(array('race' => 'Elf', 'level' => 1)),
156 | )
157 | );
158 |
159 | // Get an array of the hurt players.
160 | $hurt = $players->hurt();
161 |
162 | if (!empty($hurt))
163 | {
164 | // In this case, $hurt = array(0 => 8);
165 | // There is no entry for the second player
166 | // because that object does not have a "hurt" method.
167 | foreach ($hurt as $playerKey => $player)
168 | {
169 | // Do something with the hurt players.
170 | }
171 | };
172 | ```
173 |
174 | ## JDataDumpable
175 |
176 | `JDataDumpable` is an interface that defines a `dump` method for dumping the properties of an object as a `stdClass` with or without recursion.
177 |
178 | ## Revision History
179 |
180 | The `JData` and `JDataSet` classes were introduced in version 12.3 of the Joomla Platform.
181 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/database.md:
--------------------------------------------------------------------------------
1 | # The Database Package
2 |
3 | ## Introduction
4 |
5 | The *Database* package is designed to manage the operations of data
6 | management through the use of a generic database engine.
7 |
8 | ## Escaping strings
9 |
10 | Strings must be escaped before using them in queries (never trust any variable input, even if it comes from a previous database query from your own data source). This can be done using the `escape` and the `quote` method.
11 |
12 | The `escape` method will generally backslash unsafe characters (unually quote characters but it depends on the database engine). It also allows for optional escaping of additional characters (such as the underscore or percent when used in conjunction with a `LIKE` clause).
13 |
14 | The `quote` method will escape a string and wrap it in quotes, however, the escaping can be turned off which is desirable in some situations. The `quote` method will also accept an array of strings (added in 12.3) and return an array quoted and escaped (unless turned off) string.
15 |
16 | ```php
17 | function search($title)
18 | {
19 | // Get the database driver from the factory, or by some other suitable means.
20 | $db = JFactory::getDbo();
21 |
22 | // Search for an exact match of the title, correctly sanitising the untrusted input.
23 | $sql1 = 'SELECT * FROM #__content WHERE title = ' . $db->quote($title);
24 |
25 | // Special treatment for a LIKE clause.
26 | $search = $db->quote($db->escape($title, true) . '%', false);
27 | $sql2 = 'SELECT * FROM #__content WHERE title LIKE ' . $search;
28 |
29 | //
30 | if (is_array($title))
31 | {
32 | $sql3 = 'SELECT * FROM #__content WHERE title IN ('
33 | . implode(',', $db->quote($title)) . ')';
34 | }
35 |
36 | // Do the database calls.
37 | }
38 | ```
39 |
40 | In the first case, the title variable is simply escaped and quoted. Any quote characters in the title string will be prepended with a backslash and the whole string will be wrapped in quotes.
41 |
42 | In the second case, the example shows how to treat a search string that will be used in a `LIKE` clause. In this case, the title variable is manually escaped using `escape` with a second argument of `true`. This will force other special characters to be escaped (otherwise you could set youself up for serious performance problems if the user includes too many wildcards). Then, the result is passed to the `quote` method but escaping is turned off (because it has already been done manually).
43 |
44 | In the third case, the title variable is an array so the whole array can be passed to the `quote` method (this saves using a closure and a )
45 |
46 | Shorthand versions are available the these methods:
47 | * `q` can be used instead of `quote`
48 | * `e` can be used instead of `escape`
49 |
50 | These shorthand versions are also available when using the `JDatabaseQuery` class.
51 |
52 | ## Iterating on results
53 |
54 | The `JDatabaseIterator` class allows iteration over
55 | database results
56 |
57 | ```php
58 | $dbo = JFactory::getDbo();
59 | $iterator = $dbo->setQuery(
60 | $dbo->getQuery(true)->select('*')->from('#__content')
61 | )->getIterator();
62 | foreach ($iterator as $row)
63 | {
64 | // Deal with $row
65 | }
66 | ```
67 |
68 | It allows also to count the results.
69 |
70 | ```php
71 | $count = count($iterator);
72 | ```
73 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/date.md:
--------------------------------------------------------------------------------
1 | # The Date Package
2 |
3 | There are only two rules you need to remember when working with dates in Joomla.
4 |
5 | 1. Store all dates in GMT (Greenwich Mean Time).
6 | 2. Display all dates in local time.
7 |
8 | As long as you remember these fundamental principles, you will be able to reliably store and display dates.
9 |
10 | ## Storing in GMT
11 |
12 | There are a number of very good reasons why we store dates in GMT and not in either server local time nor user local time. Consider this situation. An author schedules an article to display at midday, Brisbane (Australia) local time. If the display is based on local time, then people in other parts of the world either see the article earlier than you (the author) or later than expected. The only way to rationally solve this is to always convert the dates to GM time before inserting them into the database.
13 |
14 | It also solves the difficulties of servers being in physically different locations around the globe. When dates are stored in GM time, the data is more portable. You can move the web site data to different locations in different time zones and it will still behave the same way.
15 |
16 | ## Displaying in Local Time
17 |
18 | Local time is determined by the Timezone Offset setting in Global Configuration. This setting is relative you you, the user, not the server on which the web site is hosted (the server offset is handled by converting dates to GM time before storing them as we explained in the previous section). The Timezone Offset is set for the site as a whole, and each registered user in the Joomla web site can maintain their own timezone offset. Because we are storing in GM time, we can physically move around the world and change our individual offset to reflect the local time of our actual location, or another desired location. If you are a company in Japan and you have web sites in several countries, you can set the timezone offset for the web site targetting an Australian audience to an appropriate local time, and the web site marketing to Brazil in another. In this way the dates you see while managing those web sites will be relative to your target audience, making it easier to schedule content for release at the right time of day.
19 |
20 | ## Using the JDate Class
21 |
22 | Joomla makes it easy to be able to store your dates in GM time and display them in local time with a class called `JDate`. Please note that this class is not for creating calendars or performing date arithmetic. It is simply a utility class for maniputating date formats and timezones.
23 |
24 | There are two ways to create a `JDate` object either directly or using the Joomla factory class.
25 |
26 | ### Creating a JDate Object Directly
27 |
28 | ```
29 | $date = new JDate;
30 | echo $date->toSql();
31 | ```
32 |
33 | Without any arguments `JDate` will assume the current GM time. If you are in Brisbane, Australia (GMT+10), the above previous example will show the date and time 10 hours behind the current local time.
34 |
35 | You can optionally supply a date and time as the first argument, and a timezone offset (in hours) in the second offset.
36 |
37 | ```
38 | $date1 = new JDate('2009-01-01 01:00:00');
39 | echo $date1->toSql();
40 |
41 | $tz = new DateTimeZone('Australia/Brisbane`);
42 | $date2 = new JDate('2009-01-01 01:00:00', 10);
43 | echo $date2->toSql();
44 | ```
45 |
46 | Where no timezone offset is specified, the date argument is used as supplied. The first example will echo `2009-01-01 01:00:00`. The second example will adjust the time back by the timezone offset. It will display `2008-12-31 15:00:00`.
47 |
48 | ### Creating a JDate Object Using JFactory
49 |
50 | The `JFactory` class has a method for creating a date object. It takes the same two optional argument but the behaviour is slightly different.
51 |
52 | ```
53 | $date3 = JFactory::getDate();
54 | // run some processor intensive code for 2 seconds
55 | $date4 = JFactory::getDate();
56 | echo $date3->toMySQL().' = '.$date4->MySQL();
57 | ```
58 |
59 | Without any argument the getDate method will assume the current time. However, this value is then cached and any future calls to getDate without any arguments will return the original object from when getDate was first called. In the previous example this simply means that `$date3` and `$date4` are the same object representing the same time. Sometimes this is useful and sometimes it can create unexpected results.
60 |
61 | Similarly if a date and/or timezone offset is supplied, these values will also be cached.
62 |
63 | You should not use `getDate` when you are logging times during an iterative process that may take more than a second to complete. For example, if you are passing text files and writing time stamps to a log file, you should use JDate directly rather then `JFactory::getDate` because it will display the same time for each log message even though the process may have taken some seconds or minutes.
64 |
65 | You should also be aware that some other code may have already called the `getDate method` (for example, in a plugin). If you are not concerned about getting the exact time then JFactory::getDate can be used effectively. If you need to know the time to the second, then you should create a new `JDate` object each time.
66 |
67 | #### Support for Alternative Date Handling
68 |
69 | Another characterist of using `JFactory::getDate` is that can load an alternative localised version of JDate from the language folder. The file should be located in the following location:
70 |
71 | `/language/en-GB/en-GB.date.php`
72 |
73 | and the class must be named `JDateen_GB` and must implement all of the methods in the `JDate` class. Because the class is a different name, you can actually extend `JDate` and simply override or add the required methods, for example:
74 |
75 | `/language/klingon/klingon.date.php`
76 |
77 | would contain the following class:
78 |
79 | ```
80 | /**
81 | * Class to display in Klingon date format
82 | */
83 | class JDateKlingon extends JDate
84 | {
85 | function toKlingon()
86 | {
87 | // Some function to convert the date
88 | return date_to_klingon($this);
89 | }
90 | }
91 | ```
92 |
93 | ## Storing Dates in the Database
94 |
95 | As previously mentioned, we must ensure that all dates are stored in GM time. There are two types of dates we need to worry about: system generated dates (like created or modifed time stamps) and user supplied dates (like publish start and finish time).
96 |
97 | ### Storing System Generated Dates
98 |
99 | A system generate date is one where we are wanting to store a timestamp based on system or server time. Common examples of a system date are the created or modifed times for an item of content, and which usually related to fields in a database table.
100 |
101 | ```
102 | // Get the table object
103 | $table = JTable::getInstance('Note', 'NoteTable');
104 |
105 | // Get a date object
106 | $date = new JDate;
107 |
108 | // Deal with other variables and then set the date
109 | if ($table->id)
110 | {
111 | // Existing item
112 | $table->modified_date = $date->toSql();
113 | }
114 | else
115 | {
116 | // New item
117 | $table->created_date = $date->toSql();
118 | }
119 | ```
120 |
121 | In this example you can see we've loaded a table object and instantiated the date object which will hold the GM time at the point it was created. There is a logic check and then a variable in the table is set to the MySQL format of the date.
122 |
123 | ### Storing User Supplied Dates
124 |
125 | Handling dates supplied by the user takes a few more steps because we assume that the user is inputing the date with respect to their local time. If you don't account for this, the dates will be stored in GM time relative to the local time on the host server, not the user.
126 |
127 | ```
128 | // Get the table object
129 | $table = JTable::getInstance('Note', 'NoteTable');
130 |
131 | // Check the date is set
132 | if (intval($table->note_date))
133 | {
134 | // Get an instance of the Application object
135 | $app = JFactory::getApplication();
136 |
137 | // Create a new date object, adjusting for the local timezone offset
138 | $date = new JDate($table->note_date, new DateTimeZone($app->getCfg('offset')));
139 |
140 | // Convert the date to MySQL format
141 | $table->note_date = $date->toSql();
142 | }
143 | else
144 | {
145 | $table->note_date = 0;
146 | }
147 | ```
148 |
149 | In this example we are imagining that the note_date field has come from a calendar control on the edit form, so it's coming through in local user time. We get the local timezone offset of the user from the configuration settings in the application. The configuration variable is called offset. For an anonymous visitor, this will be the timezone offset that as shown in the Global Configuration. For a registered user that is logged in, they may have the opportunity to provide their own timezone offset in their profile.
150 |
151 | The variable $date will now hold the local date supplied by the user, moved backwards by the timezone offset in order to arrive at GM time.
152 |
153 | ## Displaying Dates
154 |
155 | The Joomla Framework provides a convenient HTML Helper for displaying the dates that have been stored in GM time as shown below:
156 |
157 | ```
158 | note_date); ?>
159 | ```
160 |
161 | This helper takes several optional arguments apart from the date. Where no other arguments are supplied, the format is assumed to be the setting of the language string given by `DATE_FORMAT_LC1`. This is typically set to `%A, %d %B %Y` which give you an output result of `Sunday, 1 January 2009`.
162 |
163 | To specify a specific format, pass this in the second argument. The formats are defined as for the PHP strftime function.
164 |
165 | ```
166 | note_date, '%Y-%m-%d %H:%M:%S'); ?>
167 | ```
168 |
169 | This would output the date in the MySQL format `2009-01-01 01:00:00`.
170 |
171 | If we wanted to display the date in another timezone, then we can pass a custom offset as a third argument.
172 |
173 | ```
174 | note_date, '%Y-%m-%d %H:%M:%S', -5); ?>
175 | ```
176 |
177 | This will display the GM date 5 hours behind regardless of the timezone offset setting in Global Configuration.
178 |
179 | You need to be aware that calendar controls in edit forms also need to display the date adjust for local user time otherwise the date will shift on every save and/or display. Personally, I prefer to do this in the view before the date is assigned to the layout. For example in view.html.php I would include the follow code:
180 |
181 | ```
182 | // Get the item to edit
183 | $item = $this->get('Item');
184 |
185 | // Adjust for the time zones before display
186 | if (intval($item->node_date))
187 | {
188 | $item->node_date = JHtml::date($item->node_date, '%Y-%m-%d %H:%M:%S');
189 | }
190 |
191 | // Assign the item to the view for the layout to display
192 | $this->assignRef('item', $item);
193 | ```
194 |
195 | ## Other Date Solutions
196 |
197 | ### Accounting for the Local User Offset
198 |
199 | Registered users are generally allowed to set their own timezone offset. This is a variable we can easily take into account.
200 |
201 | ```
202 | $config = JFactory::getConfig();
203 | $date = JFactory::getDate($timestamp);
204 | $date->setOffset($user->getParam('timezone', $config->getValue('config.offset')));
205 | echo $date->toFormat();
206 | ```
207 | The user object stores the local user timezone offset as a parameter given by the key timezone. The offset can be passed to the getDate factory method or set using the `setOffset` method.
208 |
209 | ### Determining the UTC of Today in Local User Time
210 |
211 | When dealing with calendar applications, it's likely that you want to see what events are on today. Today usually starts at midnight local time but the UTC time will not necessarily have a zero hour value or be the same day. For example, consider if today was the 1 January 2000 in Brisabane, Australia with a timezone offset of +10 hours. Today in MySQL format would be 2000-01-01 00:00:00 so we could search for all events after that timestamp. However, if the dates are stored as UTC, the start time for the event is likely to be 1999-12-31 14:00:00. The algorithm is going to miss some events.
212 |
213 | To address this, we can find the search date by the following procedure.
214 |
215 | ```
216 | // Get the timezone offset
217 | $config = JFactory::getConfig();
218 | $offset = $config->getValue('config.offset');
219 |
220 | // Get the time now
221 | $now = JFactory::getDate();
222 |
223 | // Adjust the offset to local site or user time
224 | $now->setOffset($offset);
225 |
226 | // Get the raw date without hours, minutes and seccond (effectively midnight)
227 | $temp = $now->toFormat('%Y-%m-%d');
228 |
229 | // Pass this back into the factory method with the local site or user offset
230 | $today = JFactory::getDate($temp, $offset);
231 |
232 | // Get the UTC date for use in database queries
233 | $date = $today->toMySQL();
234 | ```
235 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/facebook.md:
--------------------------------------------------------------------------------
1 | # The Facebook Package
2 |
3 | ## Using the Facebook Package
4 |
5 | The Facebook package is designed to be a straightforward interface for working with Facebook. It is based on the Graph API. You can find documentation on the API at [http://developers.facebook.com/docs/reference/api/](http://developers.facebook.com/docs/reference/api/).
6 |
7 | ### Instantiating JFacebook
8 |
9 | Instantiating JFacebook is easy:
10 |
11 | ```php
12 | $facebook = new JFacebook;
13 | ```
14 |
15 | This creates a basic JFacebook object that can be used to access publicly available resources on facebook.com which don't require an active access token.
16 |
17 | Sometimes it is necessary to provide an active access token with the required permissions. This can be done by instantiating JFacebookOAuth.
18 |
19 | Create a Facebook application at [https://developers.facebook.com/apps](https://developers.facebook.com/apps) in order to request permissions.
20 | Instantiate JFacebookOAuth, passing the JRegistry options needed. The API key, API secret and callback URL (which is the script's path) from the Facebook application are passed through the JRegistry object. By default you have to send headers manually in your application, but if you want this to be done automatically you can set JRegistry's option 'sendheaders' to true.
21 |
22 | ```php
23 | $options = new JRegistry;
24 | $options->set('consumer_key', $consumer_key);
25 | $options->set('consumer_secret', $consumer_secret);
26 | $options->set('callback', $callback_url);
27 | $options->set('sendheaders', true);
28 | $options->set('authmethod', 'get');
29 | $oauth = new JFacebookOAuth($options);
30 |
31 | $facebook = new JFacebook($oauth);
32 | ```
33 | Now you can authenticate and request the user to authorise your application in order to get an access token, but if you already have an access token stored you can set it to the JFacebookOAuth object and if it's still valid your application will use it.
34 |
35 | ```php
36 | // Set the stored access token.
37 | $oauth->setToken($token);
38 |
39 | $access_token = $oauth->authenticate();
40 | ```
41 |
42 | When calling the authenticate() method, your stored access token will be used only if it's valid, a new one will be created if you don't have an access token or if the stored one is not valid. The method will return a valid access token that's going to be used.
43 |
44 | Set scope to the JFacebookOauth object. Scope is a comma separated list of requested permissions:
45 |
46 | ```php
47 | $oauth->setScope('read_stream,publish_stream');
48 | ```
49 |
50 | ### Accessing the JFacebook API's objects
51 |
52 | The Facebook package has 12 objects of the Graph API currently implemented:
53 | * Album
54 | * Checkin
55 | * Comment
56 | * Event
57 | * Group
58 | * Link
59 | * Note
60 | * Photo
61 | * Post
62 | * Status
63 | * User
64 | * Video
65 |
66 | Once a JFacebook object has been created, it is simple to use it to access Facebook:
67 |
68 | ```php
69 | $user = $facebook->user->getFeed($user_id);
70 | ```
71 |
72 | This will retrieve an array of Post objects containing (up to) the last 25 posts.
73 |
74 | ### More Information
75 |
76 | The following resources contain more information
77 | * [Joomla! API Reference](http://api.joomla.org)
78 | * [Facebook Graph API Reference](http://developers.facebook.com/docs/reference/api/)
79 | * [Web Application using JFacebook package.](https://gist.github.com/edaee9488fe77da6692e)
80 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/feed.md:
--------------------------------------------------------------------------------
1 | # The Feed Package
2 |
3 | ## Introduction
4 |
5 | The *Feed* package is designed to provide a straightforward way to manage interactions with RSS and atom feeds. It supports feed namespacing.
6 |
7 | ## Accessing a feed
8 |
9 | The feed package accesses an individual feed using a factory followed by the getFeed() method which takes the feed's uri as its only argument. Calls to the getFeed() method should be enclosed in a try block since they will throw runtime exceptions if either connecting with or retrieving the feed fails.
10 |
11 |
12 | ```php
13 | try
14 | {
15 | $feed = new JFeedFactory;
16 | $feedDoc = $feed->getFeed(http://feeds.joomla.org/JoomlaAnnouncements);
17 | }
18 | catch (RunTimeException $e)
19 | {
20 | $msg = JText::_('ERROR_FEED_NOT_RETRIEVED');
21 | }
22 | ```
23 |
24 |
25 | ## The Feed Class and Child Classes
26 |
27 | The factory class provides access to the feed class, its children, and their protected properties.
28 |
29 | The main class is the feed class which includes properties describing the feed as a whole: the feed uri, title, date of most recent update, description, categories and contributors. Magic get and set methods allow access to these and other methods allow more fine grained manipulation. The same is true for the child classes.
30 |
31 | The entry class, JFeedEntry, manages data about individual entries in the feed.
32 | The person class JFeedPerson, manages data about individual persons connected with the feed, typically authors, contributors or the person responsible for the feed as a whole.
33 | The link class, JFeedLink, manages data about individual links in a feed. Among other things it is used to construct html links to entries.
34 |
35 | ```php
36 | // Show the feed description
37 | echo $feedDoc->description;
38 |
39 | // Create a link to the ith item in a feed.
40 | echo ''
41 | . $feedDoc[$i]->title . '';
42 |
43 | ```
44 |
45 | JFeedParser creates an XMLReader to manage parsing feed objects. Rss and atom are supported.
46 |
47 | This example shows a simple example of how a complete feed might be rendered. Always keep in mind that not all feeds will support all elements, which means that the existence of an element should be checked for before attempting to use it. Some differences between Atom and RSS (such as use of guid) can also be incorporated by checking for their presence.
48 |
49 | You also may want to use JHtmlString::truncate or JHtmlString::truncateComplex to limit the number of characters rendered and JFilterOutput::stripImages(), JFilterOutput::stripIframes or other filtering options.
50 |
51 | ```php
52 |
53 | if (isset($feedDoc->title))
54 | {
55 | echo str_replace(''', "'", $feedDoc->title);
56 | }
57 |
58 | if (isset($feedDoc->description))
59 | {
60 | echo str_replace(''', "'", $feedDoc->description);
61 | }
62 | if (isset($feedDoc->image))
63 | {
64 | echo '';
65 | }
66 | if (!empty($this->rssDoc[0]))
67 | {
68 | // Set the number of entries to display
69 | $numentries = 5;
70 | for ($i = 0; $i < $numentries; $i++)
71 | {
72 | if (!empty($this->feedDoc[$i]->uri))
73 | {
74 | echo ''
75 | . $feedDoc[$i]->title . '';
76 | }
77 | if (!empty($feedDoc[$i]->content))
78 | {
79 | echo $feedDoc[$i]->content;
80 | }
81 | }
82 | }
83 | ```
84 |
85 |
86 | ## Namespacing Support
87 | Namespacing in feeds is used to add specialized elements to a feed. Some are widely used but individual feeds may also have customized namespacing. JFeed supports dependency injection for namespacing. Currently media and itunes support is implemented.
88 |
89 | ### More Information
90 |
91 | More information on feed related topics can be found at:
92 |
93 | [Atom Specification](http://www.atomenabled.org/developers/syndication/)
94 | [RSS Specification](http://cyber.law.harvard.edu/rss/rss.html)
95 | [W3 information on name spaces](http://feed2.w3.org/docs/howto/declare_namespaces.html)
96 | [Extending RSS with Namespaces](http://www.disobey.com/detergent/2002/extendingrss2/)
97 | [iTunes Namespace Specification](http://www.apple.com/itunes/podcasts/specs.html)
98 | [Media Namespace specifications](http://video.search.yahoo.com/mrss)
99 | [XMLReader Documentation](http://php.net/manual/en/book.xmlreader.php)
100 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-accesslevel.md:
--------------------------------------------------------------------------------
1 | # Access Level Form Field
2 |
3 | (Joomla >= 1.6)
4 |
5 | ## Description
6 |
7 | Displays a select list of access levels.
8 |
9 | ```html
10 |
11 |
18 | ```
19 |
20 | Inherits from the [List](#/en/cms/platform/form/field-list.md) field.
21 |
22 | ## Attributes
23 |
24 | Supports `class`, `disabled`, `size`, `multiple`, `onchange` and `autofocus` attributes.
25 | Supports additional `option` tags that will be appended to the list.
26 |
27 | ## Examples
28 |
29 | ### XML
30 |
31 | ```xml
32 |
36 | ```
37 |
38 | ## See Also
39 |
40 | * [Fields](#/en/cms/platform/form/fields.md)
41 | * [List field](#/en/cms/platform/form/field-list.md)
42 | * [JFormFieldAccessLevel](http://api.joomla.org/cms-3/classes/JFormFieldAccessLevel.html)
43 | * [JHtmlAccess::level](http://api.joomla.org/cms-2.5/classes/JHtmlAccess.html#method_level)
44 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-cachehandler.md:
--------------------------------------------------------------------------------
1 | # Cache Handler
2 |
3 | (Joomla >= 1.6)
4 |
5 | ## Description
6 |
7 | Displays a select list of available cache handlers.
8 |
9 | ```html
10 |
11 |
15 | ```
16 |
17 | Inherits from the [List](#/en/cms/platform/form/field-list.md) field.
18 |
19 | ## Examples
20 |
21 | ### XML
22 |
23 | ```xml
24 |
29 |
30 | ```
31 |
32 | ## See Also
33 |
34 | * [Fields](#/en/cms/platform/form/fields.md)
35 | * [List field](#/en/cms/platform/form/field-list.md)
36 | * [JFormFieldCacheHandler](http://api.joomla.org/cms-3/classes/JFormFieldCacheHandler.html)
37 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-calendar.md:
--------------------------------------------------------------------------------
1 | # Calendar Form Field
2 |
3 | (Joomla >= 1.6)
4 |
5 | ## Description
6 |
7 | Displays a popup calendar.
8 |
9 | ## Attributes
10 |
11 | Supports `size`, `maxlength`, `class`, `required`, `readonly`, `disabled`, `size`, `onchange`, `placeholder`, `autocomplete`,
12 | `filter`, `format` and `autofocus` attributes.
13 |
14 | The `filter` attribute can take one of the following values:
15 |
16 | * **SERVER_UTC** - Converts a date to UTC based on the server timezone as set in the application configuration.
17 | * **USER_UTC** - Converts a date to UTC based on the user timezone as set in the user's profile.
18 |
19 | The `format` attribute sets the format that the date will be displayed in the HTML text field.
20 | The format can be made up of the following special characters, similar to the PHP
21 | [strftime](http://us1.php.net/manual/en/function.strftime.php) function
22 |
23 | * `%a` - abbreviated weekday name
24 | * `%A` — full weekday name
25 | * `%b` — abbreviated month name
26 | * `%B` — full month name
27 | * `%C` — the century number
28 | * `%d` — the day of the month (range 01 to 31)
29 | * `%e` — the day of the month (range 1 to 31)
30 | * `%H` — hour, range 00 to 23 (24h format)
31 | * `%I` — hour, range 01 to 12 (12h format)
32 | * `%j` — day of the year (range 001 to 366)
33 | * `%k` — hour, range 0 to 23 (24h format)
34 | * `%l` — hour, range 1 to 12 (12h format)
35 | * `%m` — month, range 01 to 12
36 | * `%o` — month, range 1 to 12
37 | * `%M` — minute, range 00 to 59
38 | * `%n` — a newline character
39 | * `%p` — **PM** or **AM**
40 | * `%P` — **pm** or **am**
41 | * `%s` — UNIX time (number of seconds since 1970-01-01)
42 | * `%S` — seconds, range 00 to 59
43 | * `%t` — a tab character
44 | * `%W` — week number
45 | * `%u` — the day of the week (range 1 to 7, 1 = MON)
46 | * `%w` — the day of the week (range 0 to 6, 0 = SUN)
47 | * `%y` — year without the century (range 00 to 99)
48 | * `%Y` — year with the century
49 | * `%%` — a literal '%' character
50 |
51 | ## Examples
52 |
53 | ```xml
54 |
59 | ```
60 |
61 | ## See Also
62 |
63 | * [Fields](#/en/cms/platform/form/fields.md)
64 | * JHtmlAccess::level
65 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-captcha.md:
--------------------------------------------------------------------------------
1 | # Captcha Form Field
2 |
3 | (Joomla >= 2.5)
4 |
5 | ## Description
6 |
7 | Displays Captcha field.
8 |
9 | ## Attributes
10 |
11 | Supports `class`, `plugin`, `hidden`, `required` and `namespace` attributes.
12 |
13 | ## Examples
14 |
15 | ```xml
16 |
21 | ```
22 |
23 | ## See Also
24 |
25 | * [Fields](#/en/cms/platform/form/fields.md)
26 | * [JFormFieldCaptcha](http://api.joomla.org/cms-3/classes/JFormFieldCaptcha.html)
27 | * [JCaptcha](http://api.joomla.org/cms-3/classes/JCaptcha.html)
28 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-checkbox.md:
--------------------------------------------------------------------------------
1 | # Checkbox Form Field
2 |
3 | (Joomla >= 1.6)
4 |
5 | ## Description
6 |
7 | Displays an HTML checkbox.
8 |
9 | ## Attributes
10 |
11 | ## Examples
12 |
13 | ### XML
14 |
15 | ## See Also
16 |
17 | * [Fields](#/en/cms/platform/form/fields.md)
18 | * [JFormFieldCheckbox](http://api.joomla.org/cms-3/classes/JFormFieldCheckbox.html)
19 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-checkboxes.md:
--------------------------------------------------------------------------------
1 | # Checkboxes Form Field
2 |
3 | (Joomla >= 1.6)
4 |
5 | ## Description
6 |
7 | Displays a set of HTML checkboxes.
8 |
9 | ## Attributes
10 |
11 | ## Examples
12 |
13 | ### XML
14 |
15 | ## See Also
16 |
17 | * [Fields](#/en/cms/platform/form/fields.md)
18 | * [JFormFieldCheckboxes](http://api.joomla.org/cms-3/classes/JFormFieldCheckboxes.html)
19 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-chromestyle.md:
--------------------------------------------------------------------------------
1 | # Module Chrome Style Form Field
2 |
3 | (Joomla >= 3.0)
4 |
5 | ## Description
6 |
7 | Displays a select list of access levels.
8 |
9 | ```html
10 |
11 |
34 | ```
35 |
36 | Inherits from the [Grouped List](#/en/cms/platform/form/field-groupedlist.md) field.
37 |
38 | ## Attributes
39 |
40 | ## Examples
41 |
42 | ### XML
43 |
44 | ```xml
45 |
50 | ```
51 |
52 | ## See Also
53 |
54 | * [Fields](#/en/cms/platform/form/fields.md)
55 | * [Grouped List field](#/en/cms/platform/form/field-groupedlist.md)
56 | * [JFormFieldChromeStyle](http://api.joomla.org/cms-3/classes/JFormFieldChromeStyle.html)
57 | * [JFormFieldGroupedList](http://api.joomla.org/cms-3/classes/JFormFieldGroupedList.html)
58 | * Module Chrome Style
59 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-color.md:
--------------------------------------------------------------------------------
1 | # Color Form Field
2 |
3 | (Joomla >= 2.5)
4 |
5 | ## Description
6 |
7 | Displays either an HTML text box with a color picker control (`control` = "hue"),
8 | where the user can enter the color as a hexadecimal code (`#ff00ff`) or from the popup palette,
9 | or display a simple HTML select list (`control` = "simple").
10 |
11 | ** Default Simple List**
12 |
13 | ```html
14 |
28 | ```
29 |
30 | ## Attributes
31 |
32 | * `colors` - A comma separated list of hexadecimal color codes for the simple color list.
33 | * `control` - Control type: hue (default) or simple.
34 | * `position` - Color picker panel position: right, left, top or bottom.
35 | * `split` - A number used to split the simple color list into groups.
36 |
37 | Supports the standard `class`, `required`, `disabled`, `onchange` and `autofocus` attributes.
38 |
39 | ## Examples
40 |
41 | ### XML
42 |
43 | ```xml
44 |
47 | ```
48 |
49 | ## Changelog
50 |
51 | | Version | Description |
52 | | :-----: | ----------- |
53 | | 3.2 | The `colors`, `control`, `position`, and `split` attributes were added. |
54 |
55 |
56 | ## See Also
57 |
58 | * [Fields](#/en/cms/platform/form/fields.md)
59 | * [JFormFieldColor](http://api.joomla.org/cms-3/classes/JFormFieldColor.html)
60 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-list.md:
--------------------------------------------------------------------------------
1 | # List Form Field
2 |
3 | (Joomla >= 1.6)
4 |
5 | ## Description
6 |
7 | Displays a select list.
8 |
9 | ```html
10 |
15 | ```
16 |
17 | ## Attributes
18 |
19 | Supports `class`, `readonly`, `disabled`, `size`, `multiple`, `required`, `onchange` and `autofocus` attributes.
20 |
21 | Supports additional `option` tags that will be appended to the list.
22 |
23 | Option text is translatable. Option tags support `class`, `onclick`, `disabled` and `requires`.
24 | The `requires` attribute can have a value of "multilanguage" or "associations" or both if separated by a comma (no spaces).
25 |
26 | ## Examples
27 |
28 | ### XML
29 |
30 | ```xml
31 |
34 |
35 |
36 |
37 |
38 | ```
39 |
40 | ## See Also
41 |
42 | * [Fields](#/en/cms/platform/form/fields.md)
43 | * [JFormFieldList](http://api.joomla.org/cms-3/classes/JFormFieldList.html)
44 | * [JHtmlSelect::genericlist](http://api.joomla.org/cms-3/classes/JHtmlSelect.html#method_genericlist)
45 |
--------------------------------------------------------------------------------
/docs/en/cms/platform/form/field-text.md:
--------------------------------------------------------------------------------
1 | # Text Box Form Field
2 |
3 | (Joomla >= 1.6)
4 |
5 | ## Description
6 |
7 | Displays an HTML text box.
8 |
9 | ```html
10 |
11 | ```
12 |
13 | ## Attributes
14 |
15 | Supports `class`, `readonly`, `disabled`, `required`, `hint`, `size`, `maxlength`, `multiple`, `required`, `onchange`,
16 | `dirname`, `inputmode`, `pattern`, `filter`, `spellcheck`, `autocomplete` and `autofocus` attributes.
17 |
18 | Text fields also support suggestion in the form of `