File manager - Edit - /home/opticamezl/www/newok/com_contenthistory.tar
Back
joomla.asset.json 0000644 00000004515 15172543330 0010046 0 ustar 00 { "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json", "name": "com_contenthistory", "version": "4.0.0", "description": "Joomla CMS", "license": "GPL-2.0-or-later", "assets": [ { "name": "com_contenthistory.admin-compare-compare", "type": "script", "uri": "com_contenthistory/admin-compare-compare.min.js", "dependencies": [ "com_contenthistory.admin-compare-compare.es5" ], "attributes": { "type": "module" }, "version": "3a3f9134be7be982cf3705dd39b50dd47083cc06" }, { "name": "com_contenthistory.admin-history-modal.es5", "type": "script", "uri": "com_contenthistory/admin-history-modal-es5.min.js", "dependencies": [ "core" ], "attributes": { "nomodule": true, "defer": true }, "version": "ada35a629abc49d2c980899d78d42c5786f49ab4" }, { "name": "com_contenthistory.admin-history-modal", "type": "script", "uri": "com_contenthistory/admin-history-modal.min.js", "dependencies": [ "com_contenthistory.admin-history-modal.es5" ], "attributes": { "type": "module" }, "version": "38c9a776abe63c1569786e8a4e2e6db0ec9d5ef6" }, { "name": "com_contenthistory.admin-history-versions.es5", "type": "script", "uri": "com_contenthistory/admin-history-versions-es5.min.js", "dependencies": [ "core" ], "attributes": { "nomodule": true, "defer": true }, "version": "1f92d08e5eaf196fb3c0fb9cb1ce4943208f5353" }, { "name": "com_contenthistory.admin-history-versions", "type": "script", "uri": "com_contenthistory/admin-history-versions.min.js", "dependencies": [ "com_contenthistory.admin-history-versions.es5" ], "attributes": { "type": "module" }, "version": "973d531805b2bf1a57af65fc7c2b00d3669b73f0" }, { "name": "com_contenthistory.admin-compare-compare.es5", "type": "script", "uri": "com_contenthistory/admin-compare-compare-es5.min.js", "dependencies": [ "core", "diff" ], "attributes": { "nomodule": true, "defer": true }, "version": "1a023ac8995be80c56310f6fc2c5872dc5e13a76" } ] } index.html 0000604 00000000037 15172543330 0006540 0 ustar 00 <!DOCTYPE html><title></title> js/admin-compare-compare-es5.min.js 0000644 00000001640 15172543330 0013136 0 ustar 00 (function(){"use strict";/** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */(function(){var i=function(n){var e=document.createElement("textarea");return e.innerHTML=Joomla.sanitizeHtml(n),e.value},c=function(n,e){var m=e.nextElementSibling,u=window.Diff.diffWords(n.innerHTML,e.innerHTML),d=document.createDocumentFragment();u.forEach(function(a){var r="";a.added&&(r="#a6f3a6"),a.removed&&(r="#f8cbcb");var t=document.createElement("span");t.style.backgroundColor=r,t.style.borderRadius=".2rem",t.appendChild(document.createTextNode(i(a.value))),d.appendChild(t)}),m.appendChild(d)},l=function o(){var n=[].slice.call(document.querySelectorAll(".original"));n.forEach(function(e){c(e,e.nextElementSibling)}),document.removeEventListener("DOMContentLoaded",o)};document.addEventListener("DOMContentLoaded",l)})()})(); js/admin-compare-compare-es5.js 0000644 00000003136 15172543330 0012356 0 ustar 00 (function () { 'use strict'; /** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ (function () { // This method is used to decode HTML entities var decodeHtml = function decodeHtml(html) { var textarea = document.createElement('textarea'); textarea.innerHTML = Joomla.sanitizeHtml(html); return textarea.value; }; var compare = function compare(original, changed) { var display = changed.nextElementSibling; var diff = window.Diff.diffWords(original.innerHTML, changed.innerHTML); var fragment = document.createDocumentFragment(); diff.forEach(function (part) { var color = ''; if (part.added) { color = '#a6f3a6'; } if (part.removed) { color = '#f8cbcb'; } // @todo use the tag MARK here not SPAN var span = document.createElement('span'); span.style.backgroundColor = color; span.style.borderRadius = '.2rem'; span.appendChild(document.createTextNode(decodeHtml(part.value))); fragment.appendChild(span); }); display.appendChild(fragment); }; var onBoot = function onBoot() { var diffs = [].slice.call(document.querySelectorAll('.original')); diffs.forEach(function (fragment) { compare(fragment, fragment.nextElementSibling); }); // Cleanup document.removeEventListener('DOMContentLoaded', onBoot); }; document.addEventListener('DOMContentLoaded', onBoot); })(); })(); js/admin-history-modal-es5.min.js 0000644 00000003507 15172543330 0012663 0 ustar 00 (function(){"use strict";/** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */(function(e,r){if(!r||typeof r.Text._!="function")throw new Error("core.js was not properly initialised");e.addEventListener("DOMContentLoaded",function(){e.getElementById("toolbar-load").addEventListener("click",function(){var i=e.getElementById("toolbar-load");if(!i.disabled){var n=e.querySelectorAll('input[id*="cb"]:checked');if(n.length===1){var t=i.childNodes[1].getAttribute("data-url")+"&version_id="+n[0].value;window.parent&&t&&(window.parent.location=t)}else r.renderMessages({error:[r.Text._("COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION")]})}return!1}),e.getElementById("toolbar-preview").addEventListener("click",function(){var i=e.getElementById("toolbar-preview");if(!i.disabled){var n=["width=800, height=600, resizable=yes, scrollbars=yes"],t=e.querySelectorAll('input[id*="cb"]:checked');if(t.length===1){var a=i.childNodes[1].getAttribute("data-url")+"&version_id="+t[0].value;window.parent&&a&&window.open(a,"",n.toString())}else r.renderMessages({error:[r.Text._("COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION")]})}return!1}),e.getElementById("toolbar-compare").addEventListener("click",function(){var i=e.getElementById("toolbar-compare");if(!i.disabled){var n=["width=1000, height=600, resizable=yes, scrollbars=yes"],t=e.querySelectorAll('input[id*="cb"]:checked');if(t.length===0)r.renderMessages({error:[r.Text._("JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST")]});else if(t.length===2){var a=i.childNodes[1].getAttribute("data-url")+"&id1="+t[0].value+"&id2="+t[1].value;window.parent&&a&&window.open(a,"",n.toString())}else r.renderMessages({error:[r.Text._("COM_CONTENTHISTORY_BUTTON_SELECT_TWO_VERSIONS")]})}return!1})})})(document,Joomla)})(); js/admin-history-versions-es5.min.js 0000644 00000000505 15172543330 0013432 0 ustar 00 (function(){"use strict";/** * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */window.addEventListener("DOMContentLoaded",function(){var n=document.getElementById("versionsModal");n&&document.body.appendChild(n)})})(); js/admin-compare-compare.min.js 0000644 00000001527 15172543330 0012450 0 ustar 00 /** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */(()=>{const i=n=>{const e=document.createElement("textarea");return e.innerHTML=Joomla.sanitizeHtml(n),e.value},l=(n,e)=>{const r=e.nextElementSibling,s=window.Diff.diffWords(n.innerHTML,e.innerHTML),a=document.createDocumentFragment();s.forEach(o=>{let d="";o.added&&(d="#a6f3a6"),o.removed&&(d="#f8cbcb");const t=document.createElement("span");t.style.backgroundColor=d,t.style.borderRadius=".2rem",t.appendChild(document.createTextNode(i(o.value))),a.appendChild(t)}),r.appendChild(a)},c=()=>{[].slice.call(document.querySelectorAll(".original")).forEach(e=>{l(e,e.nextElementSibling)}),document.removeEventListener("DOMContentLoaded",c)};document.addEventListener("DOMContentLoaded",c)})(); js/admin-history-versions.min.js.gz 0000644 00000000370 15172543330 0013357 0 ustar 00 � =��j�@E��C$ �i}k�R�-���f˺v'���ߋE�v��pnY �j���=w�U9,�`ߓ���Z�B���/�H��rG��|qZq8��T�� 6�#l�S�>�����z�-{X pZ(,!A���ݡV�% �h=�4b}%/��r�e���˭c���<�W�o�> � ���$��[|�������2j��K����tߓǪ�3��e�~V�$ js/admin-history-versions.js 0000644 00000000545 15172543330 0012162 0 ustar 00 /** * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ window.addEventListener('DOMContentLoaded', () => { const versionsModal = document.getElementById('versionsModal'); if (versionsModal) { document.body.appendChild(versionsModal); } }); js/admin-history-modal-es5.min.js.gz 0000644 00000001327 15172543330 0013300 0 ustar 00 � ŕQo�6���+>���*v�"��9�ָ��"RW�!��͖!��+�^��^�M��]е(V�E:��.�w���� �+�x`�PK⣣~���ٯ��;�� 1LBv<>ey ��A l.� }ĦV��� Q�O��ڶ�_;wiD�p����h �c�=�^�g`�a/��ђ�n�n�v�3��1�f�I�iLo�����!��J_����jp��R\&�vi��eZ�":�t�k�Z�u�jt5��1m5ia����B�t�f�S7t���g�ӜP�x�Q���R�`�t7U'��J����I��{&[�L'_�u�ֱ�^������]$9<Ҷnh�U?�rŗ'r� �G{�k�$I2�`B���F�9~1\v���P���+A�I����y�Y�U���`o�i`�j�\��R�G�^pO�����pB�5c� ��X����u��E�I>�&yV�Yy6-�����eY�YU��tRVy�V���4�x����A{8����������B�jE���`� tX�Sw��?��d>b^�3���2���K�����+z���`q٘\A��:8`�.�Y��;�/ �_�?$�|6=����z1K�EZ����&�i�U����<K�ٴ(�!��������^����^��j����j�v�;�dӵ!z���uR8:x�p 8G js/admin-compare-compare-es5.min.js.gz 0000644 00000001030 15172543330 0013546 0 ustar 00 � ���nS1��} �H�Y���\JC[����@,&�����a<7I���(M�� b�gt�;:3�i�㐓ҷ�-( Sp,�n�s :��� �)�zZ=q"���(��P��q��������].��{γ6���ݨ��Bqv�Y�aB�(>�����rG"���H�(�bp��_���W| :]���H�z_H� �>�v���#�~��OI�!H]rKI� )!�_����)p���<�*i�v�ŵqH��Y�6�w�Qǐ&���!�����i�M�%�/*����6�����=��μ�Z�dꃛ�G [TKY���*��38n^±�,�,/���č�X�j#�FU搤����h��~L(��r�T��w2y�O�C[ji�gҰ����MC�� �W|�=��`����G�kmf��赉������~�esb�A����-��#:��.F%m�0 �ԺJ����)4����~�6�B��9+yz5��ěZ�^����^�W�Z��W���,� js/admin-history-modal.min.js.gz 0000644 00000001320 15172543330 0012577 0 ustar 00 � ͕]o�6���+N���s1�T�q�Ɲ-��a0U&Ol���GQ��}���Џ}��|yx���I�}�I�z��zC �$���1d5�m�¼"B�#���� Q��NNڶ�o����n�d/��@� �y� ��AWix٬�0;�ޠ��8�@W�nf�I�� �t�� �ȅ�[u��i[����@�<��Uc)kXHg[0�B�u�!롭<KP;[��[PF����(Y8B^I�ܠ���ԥ���|b u1[I�, �,�����h�|;�#k��r���$?�$��ۅ5�@�ߒu�U\*_�4������7�9jd�X��2uC%�1+�<�P>ܫx�Ѭi���N��7n�ej%��p�%4&rj�LVT=j�f�w U*?������T��ݛQ���-�+��z=�{!���:61�;��q�F�����}p����ЀM�y9��"I��i^d���篊"K�<�%���Ҥ|�\��,e�r�R���pF_.l��Fa�}R�"�k��M�x0�`�ݳ�����[o�G����ݘ-#���3��? L_�{�C��h1yN6'��:�s��^w�~ȟ�� y8�w)�?Q���yyQ�g��Y2Γr>�9)LJ�N��|v����")gӼؗx��w��ӿi)%����S�t��U��ݹ+����H+��ы����~'��) js/index.html 0000604 00000000037 15172543330 0007154 0 ustar 00 <!DOCTYPE html><title></title> js/admin-compare-compare.js 0000644 00000002665 15172543330 0011672 0 ustar 00 /** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ (() => { // This method is used to decode HTML entities const decodeHtml = html => { const textarea = document.createElement('textarea'); textarea.innerHTML = Joomla.sanitizeHtml(html); return textarea.value; }; const compare = (original, changed) => { const display = changed.nextElementSibling; const diff = window.Diff.diffWords(original.innerHTML, changed.innerHTML); const fragment = document.createDocumentFragment(); diff.forEach(part => { let color = ''; if (part.added) { color = '#a6f3a6'; } if (part.removed) { color = '#f8cbcb'; } // @todo use the tag MARK here not SPAN const span = document.createElement('span'); span.style.backgroundColor = color; span.style.borderRadius = '.2rem'; span.appendChild(document.createTextNode(decodeHtml(part.value))); fragment.appendChild(span); }); display.appendChild(fragment); }; const onBoot = () => { const diffs = [].slice.call(document.querySelectorAll('.original')); diffs.forEach(fragment => { compare(fragment, fragment.nextElementSibling); }); // Cleanup document.removeEventListener('DOMContentLoaded', onBoot); }; document.addEventListener('DOMContentLoaded', onBoot); })(); js/admin-history-versions-es5.min.js.gz 0000644 00000000412 15172543330 0014046 0 ustar 00 � M��J1����(�R��;]q]J�?B����F�s��l�"}w��n��a�GON���E���न��A ώ�S �� �F����l�OaiE0� ��x؋t����a0�̇h ���/*�� `�z�&����`qM��r`�)p�hS �]mZ#_2��y���="�"d��T�^6Lr��z����ţM@��]@�Ci#^��i�Uq��K�6���e2��|��+�g}�Jף����E js/admin-history-modal-es5.js 0000644 00000006152 15172543330 0012100 0 ustar 00 (function () { 'use strict'; /** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ (function (document, Joomla) { if (!Joomla || typeof Joomla.Text._ !== 'function') { throw new Error('core.js was not properly initialised'); } document.addEventListener('DOMContentLoaded', function () { document.getElementById('toolbar-load').addEventListener('click', function () { var toolbarLoad = document.getElementById('toolbar-load'); if (!toolbarLoad.disabled) { var ids = document.querySelectorAll('input[id*="cb"]:checked'); if (ids.length === 1) { // Add version item id to URL var url = toolbarLoad.childNodes[1].getAttribute('data-url') + "&version_id=" + ids[0].value; if (window.parent && url) { window.parent.location = url; } } else { Joomla.renderMessages({ error: [Joomla.Text._('COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION')] }); } } return false; }); document.getElementById('toolbar-preview').addEventListener('click', function () { var toolbarPreview = document.getElementById('toolbar-preview'); if (!toolbarPreview.disabled) { var windowSizeArray = ['width=800, height=600, resizable=yes, scrollbars=yes']; var ids = document.querySelectorAll('input[id*="cb"]:checked'); if (ids.length === 1) { // Add version item id to URL var url = toolbarPreview.childNodes[1].getAttribute('data-url') + "&version_id=" + ids[0].value; if (window.parent && url) { window.open(url, '', windowSizeArray.toString()); } } else { Joomla.renderMessages({ error: [Joomla.Text._('COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION')] }); } } return false; }); document.getElementById('toolbar-compare').addEventListener('click', function () { var toolbarCompare = document.getElementById('toolbar-compare'); if (!toolbarCompare.disabled) { var windowSizeArray = ['width=1000, height=600, resizable=yes, scrollbars=yes']; var ids = document.querySelectorAll('input[id*="cb"]:checked'); if (ids.length === 0) { Joomla.renderMessages({ error: [Joomla.Text._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST')] }); } else if (ids.length === 2) { // Add version item ids to URL var url = toolbarCompare.childNodes[1].getAttribute('data-url') + "&id1=" + ids[0].value + "&id2=" + ids[1].value; if (window.parent && url) { window.open(url, '', windowSizeArray.toString()); } } else { Joomla.renderMessages({ error: [Joomla.Text._('COM_CONTENTHISTORY_BUTTON_SELECT_TWO_VERSIONS')] }); } } return false; }); }); })(document, Joomla); })(); js/admin-history-versions.min.js 0000644 00000000444 15172543330 0012742 0 ustar 00 /** * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */window.addEventListener("DOMContentLoaded",()=>{const d=document.getElementById("versionsModal");d&&document.body.appendChild(d)}); js/admin-compare-compare.min.js.gz 0000644 00000001000 15172543330 0013051 0 ustar 00 � �R]kSA}�V(�a�h�R�ޢ��������fwn��ٍ�s�Ԓ�.iBb��o3s�sg���@<��0�0��)8z��ng�`�[rז�h�L�� ��v�����4Z�i|�H��T ��3�cB�>��������2A��TAA��e�3�^�t�R����TB�v5�>�v���#�����N �%[B+TE�-%@RB����W�Ŧ��^�4ʤ4���-�t�eҸפM�%o�aC�R/B�ya�B���K&_d�K�?d����m�dǏ�UUL��o�D��!"������ޣ?<��/�q����!��hN�ȍ��6����MBUl �G4#�~�)��r�T{�C2y�Oև���N�fcg3L�7 ��gw���Q�7�*��}��j�4=Y�Ү~���o���8�g�t?Ĉ�3��Q �)�C�Q(�� I���ZvǷ��?�ăPx��R��^�r�,[�^h�V�n�z�?J���7��SW js/admin-history-versions-es5.js 0000644 00000000644 15172543330 0012654 0 ustar 00 (function () { 'use strict'; /** * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ window.addEventListener('DOMContentLoaded', function () { var versionsModal = document.getElementById('versionsModal'); if (versionsModal) { document.body.appendChild(versionsModal); } }); })(); js/admin-history-modal.min.js 0000644 00000003451 15172543330 0012167 0 ustar 00 /** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */((e,r)=>{if(!r||typeof r.Text._!="function")throw new Error("core.js was not properly initialised");e.addEventListener("DOMContentLoaded",()=>{e.getElementById("toolbar-load").addEventListener("click",()=>{const i=e.getElementById("toolbar-load");if(!i.disabled){const s=e.querySelectorAll('input[id*="cb"]:checked');if(s.length===1){const t=`${i.childNodes[1].getAttribute("data-url")}&version_id=${s[0].value}`;window.parent&&t&&(window.parent.location=t)}else r.renderMessages({error:[r.Text._("COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION")]})}return!1}),e.getElementById("toolbar-preview").addEventListener("click",()=>{const i=e.getElementById("toolbar-preview");if(!i.disabled){const s=["width=800, height=600, resizable=yes, scrollbars=yes"],t=e.querySelectorAll('input[id*="cb"]:checked');if(t.length===1){const l=`${i.childNodes[1].getAttribute("data-url")}&version_id=${t[0].value}`;window.parent&&l&&window.open(l,"",s.toString())}else r.renderMessages({error:[r.Text._("COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION")]})}return!1}),e.getElementById("toolbar-compare").addEventListener("click",()=>{const i=e.getElementById("toolbar-compare");if(!i.disabled){const s=["width=1000, height=600, resizable=yes, scrollbars=yes"],t=e.querySelectorAll('input[id*="cb"]:checked');if(t.length===0)r.renderMessages({error:[r.Text._("JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST")]});else if(t.length===2){const l=`${i.childNodes[1].getAttribute("data-url")}&id1=${t[0].value}&id2=${t[1].value}`;window.parent&&l&&window.open(l,"",s.toString())}else r.renderMessages({error:[r.Text._("COM_CONTENTHISTORY_BUTTON_SELECT_TWO_VERSIONS")]})}return!1})})})(document,Joomla); js/admin-history-modal.js 0000644 00000005651 15172543330 0011411 0 ustar 00 /** * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ ((document, Joomla) => { if (!Joomla || typeof Joomla.Text._ !== 'function') { throw new Error('core.js was not properly initialised'); } document.addEventListener('DOMContentLoaded', () => { document.getElementById('toolbar-load').addEventListener('click', () => { const toolbarLoad = document.getElementById('toolbar-load'); if (!toolbarLoad.disabled) { const ids = document.querySelectorAll('input[id*="cb"]:checked'); if (ids.length === 1) { // Add version item id to URL const url = `${toolbarLoad.childNodes[1].getAttribute('data-url')}&version_id=${ids[0].value}`; if (window.parent && url) { window.parent.location = url; } } else { Joomla.renderMessages({ error: [Joomla.Text._('COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION')] }); } } return false; }); document.getElementById('toolbar-preview').addEventListener('click', () => { const toolbarPreview = document.getElementById('toolbar-preview'); if (!toolbarPreview.disabled) { const windowSizeArray = ['width=800, height=600, resizable=yes, scrollbars=yes']; const ids = document.querySelectorAll('input[id*="cb"]:checked'); if (ids.length === 1) { // Add version item id to URL const url = `${toolbarPreview.childNodes[1].getAttribute('data-url')}&version_id=${ids[0].value}`; if (window.parent && url) { window.open(url, '', windowSizeArray.toString()); } } else { Joomla.renderMessages({ error: [Joomla.Text._('COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION')] }); } } return false; }); document.getElementById('toolbar-compare').addEventListener('click', () => { const toolbarCompare = document.getElementById('toolbar-compare'); if (!toolbarCompare.disabled) { const windowSizeArray = ['width=1000, height=600, resizable=yes, scrollbars=yes']; const ids = document.querySelectorAll('input[id*="cb"]:checked'); if (ids.length === 0) { Joomla.renderMessages({ error: [Joomla.Text._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST')] }); } else if (ids.length === 2) { // Add version item ids to URL const url = `${toolbarCompare.childNodes[1].getAttribute('data-url')}&id1=${ids[0].value}&id2=${ids[1].value}`; if (window.parent && url) { window.open(url, '', windowSizeArray.toString()); } } else { Joomla.renderMessages({ error: [Joomla.Text._('COM_CONTENTHISTORY_BUTTON_SELECT_TWO_VERSIONS')] }); } } return false; }); }); })(document, Joomla); contenthistory.xml 0000644 00000002176 15172622112 0010367 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?> <extension type="component" method="upgrade"> <name>com_contenthistory</name> <author>Joomla! Project</author> <creationDate>2013-05</creationDate> <copyright>(C) 2013 Open Source Matters, Inc.</copyright> <license>GNU General Public License version 2 or later; see LICENSE.txt</license> <authorEmail>admin@joomla.org</authorEmail> <authorUrl>www.joomla.org</authorUrl> <version>4.0.0</version> <description>COM_CONTENTHISTORY_XML_DESCRIPTION</description> <namespace path="src">Joomla\Component\Contenthistory</namespace> <files folder="site"> <folder>src</folder> </files> <media destination="com_contenthistory" folder="media"> <folder>js</folder> </media> <administration> <files folder="admin"> <filename>contenthistory.xml</filename> <folder>helpers</folder> <folder>services</folder> <folder>src</folder> <folder>tmpl</folder> </files> <languages folder="admin"> <language tag="en-GB">language/en-GB/com_contenthistory.ini</language> <language tag="en-GB">language/en-GB/com_contenthistory.sys.ini</language> </languages> </administration> </extension> tmpl/preview/preview.php 0000644 00000004551 15172622112 0011377 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\Session\Session; Session::checkToken('get') or die(Text::_('JINVALID_TOKEN')); ?> <div role="main"> <h1> <?php echo Text::sprintf('COM_CONTENTHISTORY_PREVIEW_SUBTITLE_DATE', $this->item->save_date); ?> </h1> <?php if ($this->item->version_note) : ?> <h2> <?php echo Text::sprintf('COM_CONTENTHISTORY_PREVIEW_SUBTITLE', $this->item->version_note); ?> </h2> <?php endif; ?> <table class="table"> <caption class="visually-hidden"> <?php echo Text::_('COM_CONTENTHISTORY_PREVIEW_CAPTION'); ?> </caption> <thead> <tr> <th class="w-25" scope="col"><?php echo Text::_('COM_CONTENTHISTORY_PREVIEW_FIELD'); ?></th> <th scope="col"><?php echo Text::_('COM_CONTENTHISTORY_PREVIEW_VALUE'); ?></th> </tr> </thead> <tbody> <?php foreach ($this->item->data as $name => $value) : ?> <?php if (is_object($value->value)) : ?> <tr> <td colspan="2"> <?php echo $value->label; ?> </td> </tr> <?php foreach ($value->value as $subName => $subValue) : ?> <?php if ($subValue && isset($subValue->value)) : ?> <?php $subValue->value = (\is_object($subValue->value) || \is_array($subValue->value)) ? \json_encode($subValue->value, \JSON_UNESCAPED_UNICODE) : $subValue->value; ?> <tr> <th scope="row"><em> <?php echo $subValue->label; ?></em></th> <td><?php echo $subValue->value; ?></td> </tr> <?php endif; ?> <?php endforeach; ?> <?php else : ?> <tr> <th scope="row"><?php echo $value->label; ?></th> <td><?php echo $value->value; ?></td> </tr> <?php endif; ?> <?php endforeach; ?> </tbody> </table> </div> tmpl/compare/compare.php 0000644 00000007011 15172622112 0011303 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\Session\Session; Session::checkToken('get') or die(Text::_('JINVALID_TOKEN')); $version2 = $this->items[0]; $version1 = $this->items[1]; $object1 = $version1->data; $object2 = $version2->data; /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */ $wa = $this->document->getWebAssetManager(); $wa->useScript('com_contenthistory.admin-compare-compare'); ?> <div role="main"> <h1 class="mb-3"><?php echo Text::_('COM_CONTENTHISTORY_COMPARE_TITLE'); ?></h1> <table id="diff" class="table"> <caption class="visually-hidden"> <?php echo Text::_('COM_CONTENTHISTORY_COMPARE_CAPTION'); ?> </caption> <thead> <tr> <th scope="col" class="w-25"><?php echo Text::_('COM_CONTENTHISTORY_PREVIEW_FIELD'); ?></th> <th scope="col"><?php echo Text::_('COM_CONTENTHISTORY_COMPARE_OLD'); ?></th> <th scope="col"><?php echo Text::_('COM_CONTENTHISTORY_COMPARE_NEW'); ?></th> <th scope="col"><?php echo Text::_('COM_CONTENTHISTORY_COMPARE_DIFF'); ?></th> </tr> </thead> <tbody> <?php foreach ($object1 as $name => $value) : ?> <?php if (isset($value->value) && isset($object2->$name->value) && $value->value != $object2->$name->value) : ?> <?php if (is_object($value->value)) : ?> <tr> <td colspan="4"> <strong><?php echo $value->label; ?></strong> </td> </tr> <?php foreach ($value->value as $subName => $subValue) : ?> <?php $newSubValue = $object2->$name->value->$subName->value ?? ''; ?> <?php if ($subValue->value || $newSubValue) : ?> <?php if ($subValue->value != $newSubValue) : ?> <tr> <th scope="row"><em> <?php echo $subValue->label; ?></em></th> <td class="original"><?php echo htmlspecialchars($subValue->value, ENT_COMPAT, 'UTF-8'); ?></td> <td class="changed" ><?php echo htmlspecialchars($newSubValue, ENT_COMPAT, 'UTF-8'); ?></td> <td class="diff"> </td> </tr> <?php endif; ?> <?php endif; ?> <?php endforeach; ?> <?php else : ?> <tr> <th scope="row"> <?php echo $value->label; ?> </th> <td class="original"><?php echo htmlspecialchars($value->value); ?></td> <?php $object2->$name->value = is_object($object2->$name->value) ? json_encode($object2->$name->value) : $object2->$name->value; ?> <td class="changed"><?php echo htmlspecialchars($object2->$name->value, ENT_COMPAT, 'UTF-8'); ?></td> <td class="diff"> </td> </tr> <?php endif; ?> <?php endif; ?> <?php endforeach; ?> </tbody> </table> </div> tmpl/history/modal.php 0000644 00000013602 15172622112 0011027 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\Session\Session; Session::checkToken('get') or die(Text::_('JINVALID_TOKEN')); $hash = $this->state->get('sha1_hash'); $formUrl = 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' . $this->state->get('item_id') . '&' . Session::getFormToken() . '=1'; Text::script('COM_CONTENTHISTORY_BUTTON_SELECT_ONE_VERSION', true); Text::script('COM_CONTENTHISTORY_BUTTON_SELECT_TWO_VERSIONS', true); Text::script('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'); $inlineJS = <<<JS document.querySelectorAll('.js-link-open-window').forEach((link) => link.addEventListener('click', (e) => { e.preventDefault(); window.open(link.dataset.url, 'win2', 'width=800,height=600,resizable=yes,scrollbars=yes') })); JS; /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */ $wa = $this->document->getWebAssetManager(); $wa->useScript('multiselect') ->useScript('com_contenthistory.admin-history-modal') ->useScript('list-view') ->addInlineScript($inlineJS, [], ['type' => 'module']); ?> <div class="container-popup"> <div id="subhead" class="subhead noshadow mb-3"> <?php echo $this->toolbar->render(); ?> </div> <form action="<?php echo Route::_($formUrl); ?>" method="post" name="adminForm" id="adminForm"> <table class="table table-sm"> <caption class="visually-hidden"> <?php echo Text::_('COM_CONTENTHISTORY_VERSION_CAPTION'); ?> </caption> <thead> <tr> <td class="w-1 text-center"> <input class="form-check-input" type="checkbox" name="checkall-toggle" value="" title="<?php echo Text::_('JGLOBAL_CHECK_ALL'); ?>" onclick="Joomla.checkAll(this)"> </td> <th scope="col" class="w-15"> <?php echo Text::_('JDATE'); ?> </th> <th scope="col" class="w-15 d-none d-md-table-cell"> <?php echo Text::_('COM_CONTENTHISTORY_VERSION_NOTE'); ?> </th> <th scope="col" class="w-10"> <?php echo Text::_('COM_CONTENTHISTORY_KEEP_VERSION'); ?> </th> <th scope="col" class="w-15 d-none d-md-table-cell"> <?php echo Text::_('JAUTHOR'); ?> </th> <th scope="col" class="w-10 text-end"> <?php echo Text::_('COM_CONTENTHISTORY_CHARACTER_COUNT'); ?> </th> </tr> </thead> <tbody> <?php $i = 0; ?> <?php foreach ($this->items as $item) : ?> <tr class="row<?php echo $i % 2; ?>"> <td class="text-center"> <?php echo HTMLHelper::_('grid.id', $i, $item->version_id, false, 'cid', 'cb', $item->save_date); ?> </td> <th scope="row"> <a href="#" class="js-link-open-window save-date" data-url="<?php echo Route::_('index.php?option=com_contenthistory&view=preview&layout=preview&tmpl=component&' . Session::getFormToken() . '=1&version_id=' . $item->version_id); ?>"> <?php echo HTMLHelper::_('date', $item->save_date, Text::_('DATE_FORMAT_LC6')); ?> </a> <?php if ($item->sha1_hash == $hash) : ?> <span class="icon-star" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('JCURRENT'); ?></span> <?php endif; ?> </th> <td class="d-none d-md-table-cell"> <?php echo htmlspecialchars($item->version_note); ?> </td> <td> <?php if ($item->keep_forever) : ?> <button type="button" class="js-grid-item-action btn btn-secondary btn-sm" data-item-id="cb<?php echo $i; ?>" data-item-task="history.keep"> <?php echo Text::_('JYES'); ?> <span class="icon-lock" aria-hidden="true"></span> </button> <?php else : ?> <button type="button" class="js-grid-item-action btn btn-secondary btn-sm" data-item-id="cb<?php echo $i; ?>" data-item-task="history.keep"> <?php echo Text::_('JNO'); ?> </button> <?php endif; ?> </td> <td class="d-none d-md-table-cell"> <?php echo empty($item->editor) ? $item->editor_user_id : htmlspecialchars($item->editor); ?> </td> <td class="text-end"> <?php echo number_format((int) $item->character_count, 0, Text::_('DECIMALS_SEPARATOR'), Text::_('THOUSANDS_SEPARATOR')); ?> </td> </tr> <?php $i++; ?> <?php endforeach; ?> </tbody> </table> <?php /* load the pagination. */ ?> <?php echo $this->pagination->getListFooter(); ?> <input type="hidden" name="task" value=""> <input type="hidden" name="boxchecked" value="0"> <?php echo HTMLHelper::_('form.token'); ?> </form> </div> services/provider.php 0000644 00000003140 15172622112 0010727 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface; use Joomla\CMS\Extension\ComponentInterface; use Joomla\CMS\Extension\MVCComponent; use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory; use Joomla\CMS\Extension\Service\Provider\MVCFactory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; /** * The content history service provider. * * @since 4.0.0 */ return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.0.0 */ public function register(Container $container) { $container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Contenthistory')); $container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Contenthistory')); $container->set( ComponentInterface::class, function (Container $container) { $component = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class)); $component->setMVCFactory($container->get(MVCFactoryInterface::class)); return $component; } ); } }; helpers/index.html 0000604 00000000037 15172622112 0010176 0 ustar 00 <!DOCTYPE html><title></title> helpers/contenthistory.php 0000644 00000001337 15172622112 0012016 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace */ // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Categories helper. * * @since 3.2 * * @deprecated 4.3 will be removed in 6.0 * Use \Joomla\Component\Contenthistory\Administrator\Helper\ContenthistoryHelper instead */ class ContenthistoryHelper extends \Joomla\Component\Contenthistory\Administrator\Helper\ContenthistoryHelper { } src/View/History/HtmlView.php 0000644 00000010442 15172622112 0012156 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\View\History; use Joomla\CMS\Factory; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; use Joomla\CMS\Pagination\Pagination; use Joomla\CMS\Router\Route; use Joomla\CMS\Session\Session; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarFactoryInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * View class for a list of contenthistory. * * @since 3.2 */ class HtmlView extends BaseHtmlView { /** * An array of items * * @var array */ protected $items; /** * The model state * * @var Pagination */ protected $pagination; /** * The model state * * @var \Joomla\CMS\Object\CMSObject */ protected $state; /** * The toolbar for the history modal. Note this is rendered inside the modal rather than using the regular module * * @var Toolbar */ protected $toolbar; /** * Method to display the view. * * @param string $tpl A template file to load. [optional] * * @return void * * @since 3.2 */ public function display($tpl = null) { $this->state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); // Check for errors. if (count($errors = $this->get('Errors'))) { throw new GenericDataException(implode("\n", $errors), 500); } $this->toolbar = $this->addToolbar(); parent::display($tpl); } /** * Add the page toolbar. * * @return Toolbar * * @since 4.0.0 */ protected function addToolbar(): Toolbar { /** @var Toolbar $toolbar */ $toolbar = Factory::getContainer()->get(ToolbarFactoryInterface::class)->createToolbar('toolbar'); // Cache a session token for reuse throughout. $token = Session::getFormToken(); // Clean up input to ensure a clean url. $filter = InputFilter::getInstance(); $aliasArray = explode('.', $this->state->item_id); if ($aliasArray[1] === 'category') { $option = 'com_categories'; $append = '&extension=' . $filter->clean($aliasArray[0], 'cmd'); } else { $option = $aliasArray[0]; $append = ''; } $task = $filter->clean($aliasArray[1], 'cmd') . '.loadhistory'; // Build the final urls. $loadUrl = Route::_('index.php?option=' . $filter->clean($option, 'cmd') . $append . '&task=' . $task . '&' . $token . '=1'); $previewUrl = Route::_('index.php?option=com_contenthistory&view=preview&layout=preview&tmpl=component&' . $token . '=1'); $compareUrl = Route::_('index.php?option=com_contenthistory&view=compare&layout=compare&tmpl=component&' . $token . '=1'); $toolbar->basicButton('load', 'COM_CONTENTHISTORY_BUTTON_LOAD') ->attributes(['data-url' => $loadUrl]) ->icon('icon-upload') ->buttonClass('btn btn-success') ->listCheck(true); $toolbar->basicButton('preview', 'COM_CONTENTHISTORY_BUTTON_PREVIEW') ->attributes(['data-url' => $previewUrl]) ->icon('icon-search') ->listCheck(true); $toolbar->basicButton('compare', 'COM_CONTENTHISTORY_BUTTON_COMPARE') ->attributes(['data-url' => $compareUrl]) ->icon('icon-search-plus') ->listCheck(true); $toolbar->basicButton('keep', 'COM_CONTENTHISTORY_BUTTON_KEEP', 'history.keep') ->buttonClass('btn btn-inverse') ->icon('icon-lock') ->listCheck(true); $toolbar->basicButton('delete', 'COM_CONTENTHISTORY_BUTTON_DELETE', 'history.delete') ->buttonClass('btn btn-danger') ->icon('icon-times') ->listCheck(true); return $toolbar; } } src/View/Preview/HtmlView.php 0000644 00000003103 15172622112 0012132 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\View\Preview; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * View class for a list of contenthistory. * * @since 1.5 */ class HtmlView extends BaseHtmlView { /** * An array of items * * @var \stdClass|false */ protected $item; /** * The model state * * @var \Joomla\CMS\Object\CMSObject */ protected $state; /** * Method to display the view. * * @param string $tpl A template file to load. [optional] * * @return void * * @since 3.2 */ public function display($tpl = null) { $this->state = $this->get('State'); $this->item = $this->get('Item'); if (false === $this->item) { $this->getLanguage()->load('com_content', JPATH_SITE, null, true); throw new \Exception(Text::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'), 404); } // Check for errors. if (count($errors = $this->get('Errors'))) { throw new GenericDataException(implode("\n", $errors), 500); } parent::display($tpl); } } src/View/Compare/HtmlView.php 0000644 00000002506 15172622112 0012105 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\View\Compare; use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * View class for a list of contenthistory. * * @since 3.2 */ class HtmlView extends BaseHtmlView { /** * An array of items * * @var array */ protected $items; /** * The model state * * @var \Joomla\CMS\Object\CMSObject */ protected $state; /** * Method to display the view. * * @param string $tpl A template file to load. [optional] * * @return void * * @since 3.2 */ public function display($tpl = null) { $this->state = $this->get('State'); $this->items = $this->get('Items'); // Check for errors. if (count($errors = $this->get('Errors'))) { throw new GenericDataException(implode("\n", $errors), 500); } parent::display($tpl); } } src/Controller/HistoryController.php 0000644 00000006330 15172622112 0013675 0 ustar 00 <?php /** * @package Joomla.API * @subpackage com_contenthistory * * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Api\Controller; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\ApiController; use Joomla\CMS\MVC\Controller\Exception; use Joomla\Component\Contenthistory\Administrator\Model\HistoryModel; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * The history controller * * @since 4.0.0 */ class HistoryController extends ApiController { /** * The content type of the item. * * @var string * @since 4.0.0 */ protected $contentType = 'history'; /** * The default view for the display method. * * @var string * @since 3.0 */ protected $default_view = 'history'; /** * Basic display of a list view * * @return static A \JControllerLegacy object to support chaining. * * @since 4.0.0 */ public function displayList() { $this->modelState->set('type_alias', $this->getTypeAliasFromInput()); $this->modelState->set('type_id', $this->getTypeIdFromInput()); $this->modelState->set('item_id', $this->getTypeAliasFromInput() . '.' . $this->getItemIdFromInput()); $this->modelState->set('list.ordering', 'h.save_date'); $this->modelState->set('list.direction', 'DESC'); return parent::displayList(); } /** * Method to edit an existing record. * * @return static A \JControllerLegacy object to support chaining. * * @since 4.0.0 */ public function keep() { /** @var HistoryModel $model */ $model = $this->getModel($this->contentType); if (!$model) { throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_MODEL_CREATE')); } $recordId = $this->input->getInt('id'); if (!$recordId) { throw new Exception\ResourceNotFound(Text::_('JLIB_APPLICATION_ERROR_RECORD'), 404); } $cid = [$recordId]; if (!$model->keep($cid)) { throw new Exception\Save(Text::plural('COM_CONTENTHISTORY_N_ITEMS_KEEP_TOGGLE', \count($cid))); } return $this; } /** * Get item id from input * * @return string * * @since 4.0.0 */ private function getItemIdFromInput() { return $this->input->exists('id') ? $this->input->get('id') : $this->input->post->get('id'); } /** * Get type id from input * * @return string * * @since 4.0.0 */ private function getTypeIdFromInput() { return $this->input->exists('type_id') ? $this->input->get('type_id') : $this->input->post->get('type_id'); } /** * Get type alias from input * * @return string * * @since 4.0.0 */ private function getTypeAliasFromInput() { return $this->input->exists('type_alias') ? $this->input->get('type_alias') : $this->input->post->get('type_alias'); } } src/Controller/DisplayController.php 0000644 00000001077 15172622112 0013644 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\Controller; use Joomla\CMS\MVC\Controller\BaseController; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Contenthistory Controller * * @since 3.2 */ class DisplayController extends BaseController { } src/Controller/PreviewController.php 0000644 00000002115 15172622112 0013652 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\Controller; use Joomla\CMS\MVC\Controller\BaseController; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Contenthistory list controller class. * * @since 3.2 */ class PreviewController extends BaseController { /** * Proxy for getModel. * * @param string $name The name of the model * @param string $prefix The prefix for the model * @param array $config An additional array of parameters * * @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model * * @since 3.2 */ public function getModel($name = 'Preview', $prefix = 'Administrator', $config = ['ignore_request' => true]) { return parent::getModel($name, $prefix, $config); } } src/Dispatcher/Dispatcher.php 0000644 00000002106 15172622112 0012216 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\Dispatcher; use Joomla\CMS\Access\Exception\NotAllowed; use Joomla\CMS\Dispatcher\ComponentDispatcher; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * ComponentDispatcher class for com_associations * * @since 4.0.0 */ class Dispatcher extends ComponentDispatcher { /** * Method to check component access permission * * @since 4.0.0 * * @return void * * @throws \Exception|NotAllowed */ protected function checkAccess() { // Check the user has permission to access this component if in the backend if ($this->app->getIdentity()->guest) { throw new NotAllowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403); } } } src/Model/HistoryModel.php 0000644 00000030664 15172622112 0011536 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\Model; use Joomla\CMS\Access\Exception\NotAllowed; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Helper\CMSHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; use Joomla\CMS\Table\ContentHistory; use Joomla\CMS\Table\ContentType; use Joomla\CMS\Table\Table; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Methods supporting a list of contenthistory records. * * @since 3.2 */ class HistoryModel extends ListModel { /** * Constructor. * * @param array $config An optional associative array of configuration settings. * @param MVCFactoryInterface $factory The factory. * * @see \Joomla\CMS\MVC\Model\BaseDatabaseModel * @since 3.2 */ public function __construct($config = [], MVCFactoryInterface $factory = null) { if (empty($config['filter_fields'])) { $config['filter_fields'] = [ 'version_id', 'h.version_id', 'version_note', 'h.version_note', 'save_date', 'h.save_date', 'editor_user_id', 'h.editor_user_id', ]; } parent::__construct($config, $factory); } /** * Method to test whether a record is editable * * @param ContentHistory $record A Table object. * * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. * * @since 3.2 */ protected function canEdit($record) { if (empty($record->item_id)) { return false; } /** * Make sure user has edit privileges for this content item. Note that we use edit permissions * for the content item, not delete permissions for the content history row. */ $user = $this->getCurrentUser(); if ($user->authorise('core.edit', $record->item_id)) { return true; } // Finally try session (this catches edit.own case too) /** @var ContentType $contentTypeTable */ $contentTypeTable = $this->getTable('ContentType'); $typeAlias = explode('.', $record->item_id); $id = array_pop($typeAlias); $typeAlias = implode('.', $typeAlias); $contentTypeTable->load(['type_alias' => $typeAlias]); $typeEditables = (array) Factory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); $result = in_array((int) $id, $typeEditables); return $result; } /** * Method to test whether a history record can be deleted. Note that we check whether we have edit permissions * for the content item row. * * @param ContentHistory $record A Table object. * * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. * * @since 3.6 */ protected function canDelete($record) { return $this->canEdit($record); } /** * Method to delete one or more records from content history table. * * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 3.2 */ public function delete(&$pks) { $pks = (array) $pks; $table = $this->getTable(); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ((int) $table->keep_forever === 1) { unset($pks[$i]); continue; } if ($this->canEdit($table)) { if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { try { Log::add($error, Log::WARNING, 'jerror'); } catch (\RuntimeException $exception) { Factory::getApplication()->enqueueMessage($error, 'warning'); } return false; } else { try { Log::add(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), Log::WARNING, 'jerror'); } catch (\RuntimeException $exception) { Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'warning'); } return false; } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to get an array of data items. * * @return mixed An array of data items on success, false on failure. * * @since 3.4.5 * * @throws NotAllowed Thrown if not authorised to edit an item */ public function getItems() { $items = parent::getItems(); $user = $this->getCurrentUser(); if ($items === false) { return false; } // This should be an array with at least one element if (!is_array($items) || !isset($items[0])) { return $items; } // Access check if (!$user->authorise('core.edit', $items[0]->item_id) && !$this->canEdit($items[0])) { throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); } return $items; } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return Table A Table object * * @since 3.2 */ public function getTable($type = 'ContentHistory', $prefix = 'Joomla\\CMS\\Table\\', $config = []) { return Table::getInstance($type, $prefix, $config); } /** * Method to toggle on and off the keep forever value for one or more records from content history table. * * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 3.2 */ public function keep(&$pks) { $pks = (array) $pks; $table = $this->getTable(); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($this->canEdit($table)) { $table->keep_forever = $table->keep_forever ? 0 : 1; if (!$table->store()) { $this->setError($table->getError()); return false; } } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { try { Log::add($error, Log::WARNING, 'jerror'); } catch (\RuntimeException $exception) { Factory::getApplication()->enqueueMessage($error, 'warning'); } return false; } else { try { Log::add(Text::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), Log::WARNING, 'jerror'); } catch (\RuntimeException $exception) { Factory::getApplication()->enqueueMessage(Text::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), 'warning'); } return false; } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. * @param string $direction An optional direction (asc|desc). * * @return void * * @since 3.2 */ protected function populateState($ordering = 'h.save_date', $direction = 'DESC') { $input = Factory::getApplication()->getInput(); $itemId = $input->get('item_id', '', 'string'); $this->setState('item_id', $itemId); $this->setState('sha1_hash', $this->getSha1Hash()); // Load the parameters. $params = ComponentHelper::getParams('com_contenthistory'); $this->setState('params', $params); // List state information. parent::populateState($ordering, $direction); } /** * Build an SQL query to load the list data. * * @return \Joomla\Database\DatabaseQuery * * @since 3.2 */ protected function getListQuery() { // Create a new query object. $db = $this->getDatabase(); $query = $db->getQuery(true); $itemId = $this->getState('item_id'); // Select the required fields from the table. $query->select( $this->getState( 'list.select', [ $db->quoteName('h.version_id'), $db->quoteName('h.item_id'), $db->quoteName('h.version_note'), $db->quoteName('h.save_date'), $db->quoteName('h.editor_user_id'), $db->quoteName('h.character_count'), $db->quoteName('h.sha1_hash'), $db->quoteName('h.version_data'), $db->quoteName('h.keep_forever'), ] ) ) ->from($db->quoteName('#__history', 'h')) ->where($db->quoteName('h.item_id') . ' = :itemid') ->bind(':itemid', $itemId, ParameterType::STRING) // Join over the users for the editor ->select($db->quoteName('uc.name', 'editor')) ->join( 'LEFT', $db->quoteName('#__users', 'uc'), $db->quoteName('uc.id') . ' = ' . $db->quoteName('h.editor_user_id') ); // Add the list ordering clause. $orderCol = $this->state->get('list.ordering'); $orderDirn = $this->state->get('list.direction'); $query->order($db->quoteName($orderCol) . $orderDirn); return $query; } /** * Get the sha1 hash value for the current item being edited. * * @return string sha1 hash of row data * * @since 3.2 */ protected function getSha1Hash() { $result = false; $item_id = Factory::getApplication()->getInput()->getCmd('item_id', ''); $typeAlias = explode('.', $item_id); Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/' . $typeAlias[0] . '/tables'); $typeTable = $this->getTable('ContentType'); $typeTable->load(['type_alias' => $typeAlias[0] . '.' . $typeAlias[1]]); $contentTable = $typeTable->getContentTable(); if ($contentTable && $contentTable->load($typeAlias[2])) { $helper = new CMSHelper(); $dataObject = $helper->getDataObject($contentTable); $result = $this->getTable('ContentHistory')->getSha1(json_encode($dataObject), $typeTable); } return $result; } } src/Model/PreviewModel.php 0000644 00000011470 15172622112 0011510 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\Model; use Joomla\CMS\Access\Exception\NotAllowed; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\ItemModel; use Joomla\CMS\Table\ContentHistory; use Joomla\CMS\Table\ContentType; use Joomla\CMS\Table\Table; use Joomla\Component\Contenthistory\Administrator\Helper\ContenthistoryHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Methods supporting a list of contenthistory records. * * @since 3.2 */ class PreviewModel extends ItemModel { /** * Method to get a version history row. * * @param integer $pk The id of the item * * @return \stdClass|boolean On success, standard object with row data. False on failure. * * @since 3.2 * * @throws NotAllowed Thrown if not authorised to edit an item */ public function getItem($pk = null) { /** @var ContentHistory $table */ $table = $this->getTable('ContentHistory'); $versionId = Factory::getApplication()->getInput()->getInt('version_id'); if (!$versionId || \is_array($versionId) || !$table->load($versionId)) { return false; } $user = $this->getCurrentUser(); // Access check if (!$user->authorise('core.edit', $table->item_id) && !$this->canEdit($table)) { throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); } $result = new \stdClass(); $result->version_note = $table->version_note; $result->data = ContenthistoryHelper::prepareData($table); // Let's use custom calendars when present $result->save_date = HTMLHelper::_('date', $table->save_date, Text::_('DATE_FORMAT_LC6')); $dateProperties = [ 'modified_time', 'created_time', 'modified', 'created', 'checked_out_time', 'publish_up', 'publish_down', ]; $nullDate = $this->getDatabase()->getNullDate(); foreach ($dateProperties as $dateProperty) { if ( property_exists($result->data, $dateProperty) && $result->data->$dateProperty->value !== null && $result->data->$dateProperty->value !== $nullDate ) { $result->data->$dateProperty->value = HTMLHelper::_( 'date', $result->data->$dateProperty->value, Text::_('DATE_FORMAT_LC6') ); } } return $result; } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return Table A Table object * * @since 3.2 */ public function getTable($type = 'ContentHistory', $prefix = 'Joomla\\CMS\\Table\\', $config = []) { return Table::getInstance($type, $prefix, $config); } /** * Method to test whether a record is editable * * @param ContentHistory $record A Table object. * * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. * * @since 3.6 */ protected function canEdit($record) { $result = false; if (!empty($record->item_id)) { /** * Make sure user has edit privileges for this content item. Note that we use edit permissions * for the content item, not delete permissions for the content history row. */ $user = $this->getCurrentUser(); $result = $user->authorise('core.edit', $record->item_id); // Finally try session (this catches edit.own case too) if (!$result) { /** @var ContentType $contentTypeTable */ $contentTypeTable = $this->getTable('ContentType'); $typeAlias = explode('.', $record->item_id); $id = array_pop($typeAlias); $typeAlias = implode('.', $typeAlias); $typeEditables = (array) Factory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); $result = in_array((int) $id, $typeEditables); } } return $result; } } src/Model/CompareModel.php 0000644 00000014147 15172622112 0011461 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\Model; use Joomla\CMS\Access\Exception\NotAllowed; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\ListModel; use Joomla\CMS\Table\ContentHistory; use Joomla\CMS\Table\ContentType; use Joomla\CMS\Table\Table; use Joomla\Component\Contenthistory\Administrator\Helper\ContenthistoryHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Methods supporting a list of contenthistory records. * * @since 3.2 */ class CompareModel extends ListModel { /** * Method to get a version history row. * * @return array|boolean On success, array of populated tables. False on failure. * * @since 3.2 * * @throws NotAllowed Thrown if not authorised to edit an item */ public function getItems() { $input = Factory::getApplication()->getInput(); /** @var ContentHistory $table1 */ $table1 = $this->getTable('ContentHistory'); /** @var ContentHistory $table2 */ $table2 = $this->getTable('ContentHistory'); $id1 = $input->getInt('id1'); $id2 = $input->getInt('id2'); if (!$id1 || \is_array($id1) || !$id2 || \is_array($id2)) { $this->setError(Text::_('COM_CONTENTHISTORY_ERROR_INVALID_ID')); return false; } $result = []; if (!$table1->load($id1) || !$table2->load($id2)) { $this->setError(Text::_('COM_CONTENTHISTORY_ERROR_VERSION_NOT_FOUND')); // Assume a failure to load the content means broken data, abort mission return false; } // Get the first history record's content type record so we can check ACL /** @var ContentType $contentTypeTable */ $contentTypeTable = $this->getTable('ContentType'); $typeAlias = explode('.', $table1->item_id); array_pop($typeAlias); $typeAlias = implode('.', $typeAlias); if (!$contentTypeTable->load(['type_alias' => $typeAlias])) { $this->setError(Text::_('COM_CONTENTHISTORY_ERROR_FAILED_LOADING_CONTENT_TYPE')); // Assume a failure to load the content type means broken data, abort mission return false; } $user = $this->getCurrentUser(); // Access check if (!$user->authorise('core.edit', $table1->item_id) && !$this->canEdit($table1)) { throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); } $nullDate = $this->getDatabase()->getNullDate(); foreach ([$table1, $table2] as $table) { $object = new \stdClass(); $object->data = ContenthistoryHelper::prepareData($table); $object->version_note = $table->version_note; // Let's use custom calendars when present $object->save_date = HTMLHelper::_('date', $table->save_date, Text::_('DATE_FORMAT_LC6')); $dateProperties = [ 'modified_time', 'created_time', 'modified', 'created', 'checked_out_time', 'publish_up', 'publish_down', ]; foreach ($dateProperties as $dateProperty) { if ( property_exists($object->data, $dateProperty) && $object->data->$dateProperty->value !== null && $object->data->$dateProperty->value !== $nullDate ) { $object->data->$dateProperty->value = HTMLHelper::_( 'date', $object->data->$dateProperty->value, Text::_('DATE_FORMAT_LC6') ); } } $result[] = $object; } return $result; } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return Table A Table object * * @since 3.2 */ public function getTable($type = 'Contenthistory', $prefix = 'Joomla\\CMS\\Table\\', $config = []) { return Table::getInstance($type, $prefix, $config); } /** * Method to test whether a record is editable * * @param ContentHistory $record A Table object. * * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. * * @since 3.6 */ protected function canEdit($record) { $result = false; if (!empty($record->item_id)) { /** * Make sure user has edit privileges for this content item. Note that we use edit permissions * for the content item, not delete permissions for the content history row. */ $user = $this->getCurrentUser(); $result = $user->authorise('core.edit', $record->item_id); // Finally try session (this catches edit.own case too) if (!$result) { /** @var ContentType $contentTypeTable */ $contentTypeTable = $this->getTable('ContentType'); $typeAlias = explode('.', $record->item_id); $id = array_pop($typeAlias); $typeAlias = implode('.', $typeAlias); $contentTypeTable->load(['type_alias' => $typeAlias]); $typeEditables = (array) Factory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); $result = in_array((int) $id, $typeEditables); } } return $result; } } src/Helper/ContenthistoryHelper.php 0000644 00000031725 15172622112 0013466 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Administrator\Helper; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\File; use Joomla\CMS\Filesystem\Folder; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Language\Text; use Joomla\CMS\Table\ContentHistory; use Joomla\CMS\Table\ContentType; use Joomla\CMS\Table\Table; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Categories helper. * * @since 3.2 */ class ContenthistoryHelper { /** * Method to put all field names, including nested ones, in a single array for easy lookup. * * @param \stdClass $object Standard class object that may contain one level of nested objects. * * @return array Associative array of all field names, including ones in a nested object. * * @since 3.2 */ public static function createObjectArray($object) { $result = []; if ($object === null) { return $result; } foreach ($object as $name => $value) { $result[$name] = $value; if (is_object($value)) { foreach ($value as $subName => $subValue) { $result[$subName] = $subValue; } } } return $result; } /** * Method to decode JSON-encoded fields in a standard object. Used to unpack JSON strings in the content history data column. * * @param string $jsonString JSON String to convert to an object. * * @return \stdClass Object with any JSON-encoded fields unpacked. * * @since 3.2 */ public static function decodeFields($jsonString) { $object = json_decode($jsonString); if (is_object($object)) { foreach ($object as $name => $value) { if (!is_null($value) && $subObject = json_decode($value)) { $object->$name = $subObject; } } } return $object; } /** * Method to get field labels for the fields in the JSON-encoded object. * First we see if we can find translatable labels for the fields in the object. * We translate any we can find and return an array in the format object->name => label. * * @param \stdClass $object Standard class object in the format name->value. * @param ContentType $typesTable Table object with content history options. * * @return \stdClass Contains two associative arrays. * $formValues->labels in the format name => label (for example, 'id' => 'Article ID'). * $formValues->values in the format name => value (for example, 'state' => 'Published'. * This translates the text from the selected option in the form. * * @since 3.2 */ public static function getFormValues($object, ContentType $typesTable) { $labels = []; $values = []; $expandedObjectArray = static::createObjectArray($object); static::loadLanguageFiles($typesTable->type_alias); if ($formFile = static::getFormFile($typesTable)) { if ($xml = simplexml_load_file($formFile)) { // Now we need to get all of the labels from the form $fieldArray = $xml->xpath('//field'); $fieldArray = array_merge($fieldArray, $xml->xpath('//fields')); foreach ($fieldArray as $field) { if ($label = (string) $field->attributes()->label) { $labels[(string) $field->attributes()->name] = Text::_($label); } } // Get values for any list type fields $listFieldArray = $xml->xpath('//field[@type="list" or @type="radio"]'); foreach ($listFieldArray as $field) { $name = (string) $field->attributes()->name; if (isset($expandedObjectArray[$name])) { $optionFieldArray = $field->xpath('option[@value="' . $expandedObjectArray[$name] . '"]'); $valueText = null; if (is_array($optionFieldArray) && count($optionFieldArray)) { $valueText = trim((string) $optionFieldArray[0]); } $values[(string) $field->attributes()->name] = Text::_($valueText); } } } } $result = new \stdClass(); $result->labels = $labels; $result->values = $values; return $result; } /** * Method to get the XML form file for this component. Used to get translated field names for history preview. * * @param ContentType $typesTable Table object with content history options. * * @return mixed \JModel object if successful, false if no model found. * * @since 3.2 */ public static function getFormFile(ContentType $typesTable) { // First, see if we have a file name in the $typesTable $options = json_decode($typesTable->content_history_options); if (is_object($options) && isset($options->formFile) && is_file(JPATH_ROOT . '/' . $options->formFile)) { $result = JPATH_ROOT . '/' . $options->formFile; } else { $aliasArray = explode('.', $typesTable->type_alias); $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; $path = Folder::makeSafe(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/'); array_shift($aliasArray); $file = File::makeSafe(implode('.', $aliasArray) . '.xml'); $result = is_file($path . $file) ? $path . $file : false; } return $result; } /** * Method to query the database using values from lookup objects. * * @param \stdClass $lookup The std object with the values needed to do the query. * @param mixed $value The value used to find the matching title or name. Typically the id. * * @return mixed Value from database (for example, name or title) on success, false on failure. * * @since 3.2 */ public static function getLookupValue($lookup, $value) { $result = false; if (isset($lookup->sourceColumn) && isset($lookup->targetTable) && isset($lookup->targetColumn) && isset($lookup->displayColumn)) { $db = Factory::getDbo(); $value = (int) $value; $query = $db->getQuery(true); $query->select($db->quoteName($lookup->displayColumn)) ->from($db->quoteName($lookup->targetTable)) ->where($db->quoteName($lookup->targetColumn) . ' = :value') ->bind(':value', $value, ParameterType::INTEGER); $db->setQuery($query); try { $result = $db->loadResult(); } catch (\Exception $e) { // Ignore any errors and just return false return false; } } return $result; } /** * Method to remove fields from the object based on values entered in the #__content_types table. * * @param \stdClass $object Object to be passed to view layout file. * @param ContentType $typeTable Table object with content history options. * * @return \stdClass object with hidden fields removed. * * @since 3.2 */ public static function hideFields($object, ContentType $typeTable) { if ($options = json_decode($typeTable->content_history_options)) { if (isset($options->hideFields) && is_array($options->hideFields)) { foreach ($options->hideFields as $field) { unset($object->$field); } } } return $object; } /** * Method to load the language files for the component whose history is being viewed. * * @param string $typeAlias The type alias, for example 'com_content.article'. * * @return void * * @since 3.2 */ public static function loadLanguageFiles($typeAlias) { $aliasArray = explode('.', $typeAlias); if (is_array($aliasArray) && count($aliasArray) == 2) { $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; $lang = Factory::getLanguage(); /** * Loading language file from the administrator/language directory then * loading language file from the administrator/components/extension/language directory */ $lang->load($component, JPATH_ADMINISTRATOR) || $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); // Force loading of backend global language file $lang->load('joomla', Path::clean(JPATH_ADMINISTRATOR)); } } /** * Method to create object to pass to the layout. Format is as follows: * field is std object with name, value. * * Value can be a std object with name, value pairs. * * @param \stdClass $object The std object from the JSON string. Can be nested 1 level deep. * @param \stdClass $formValues Standard class of label and value in an associative array. * * @return \stdClass Object with translated labels where available * * @since 3.2 */ public static function mergeLabels($object, $formValues) { $result = new \stdClass(); if ($object === null) { return $result; } $labelsArray = $formValues->labels; $valuesArray = $formValues->values; foreach ($object as $name => $value) { $result->$name = new \stdClass(); $result->$name->name = $name; $result->$name->value = $valuesArray[$name] ?? $value; $result->$name->label = $labelsArray[$name] ?? $name; if (is_object($value)) { $subObject = new \stdClass(); foreach ($value as $subName => $subValue) { $subObject->$subName = new \stdClass(); $subObject->$subName->name = $subName; $subObject->$subName->value = $valuesArray[$subName] ?? $subValue; $subObject->$subName->label = $labelsArray[$subName] ?? $subName; $result->$name->value = $subObject; } } } return $result; } /** * Method to prepare the object for the preview and compare views. * * @param ContentHistory $table Table object loaded with data. * * @return \stdClass Object ready for the views. * * @since 3.2 */ public static function prepareData(ContentHistory $table) { $object = static::decodeFields($table->version_data); $typesTable = Table::getInstance('ContentType', 'Joomla\\CMS\\Table\\'); $typeAlias = explode('.', $table->item_id); array_pop($typeAlias); $typesTable->load(['type_alias' => implode('.', $typeAlias)]); $formValues = static::getFormValues($object, $typesTable); $object = static::mergeLabels($object, $formValues); $object = static::hideFields($object, $typesTable); $object = static::processLookupFields($object, $typesTable); return $object; } /** * Method to process any lookup values found in the content_history_options column for this table. * This allows category title and user name to be displayed instead of the id column. * * @param \stdClass $object The std object from the JSON string. Can be nested 1 level deep. * @param ContentType $typesTable Table object loaded with data. * * @return \stdClass Object with lookup values inserted. * * @since 3.2 */ public static function processLookupFields($object, ContentType $typesTable) { if ($options = json_decode($typesTable->content_history_options)) { if (isset($options->displayLookup) && is_array($options->displayLookup)) { foreach ($options->displayLookup as $lookup) { $sourceColumn = $lookup->sourceColumn ?? false; $sourceValue = $object->$sourceColumn->value ?? false; if ($sourceColumn && $sourceValue && ($lookupValue = static::getLookupValue($lookup, $sourceValue))) { $object->$sourceColumn->value = $lookupValue; } } } } return $object; } } src/View/History/JsonapiView.php 0000644 00000002525 15172626010 0012661 0 ustar 00 <?php /** * @package Joomla.API * @subpackage com_contenthistory * * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Contenthistory\Api\View\History; use Joomla\CMS\MVC\View\JsonApiView as BaseApiView; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * The history view * * @since 4.0.0 */ class JsonapiView extends BaseApiView { /** * The fields to render items in the documents * * @var array * @since 4.0.0 */ protected $fieldsToRenderList = [ 'id', 'ucm_item_id', 'ucm_type_id', 'version_note', 'save_date', 'editor_user_id', 'character_count', 'sha1_hash', 'version_data', 'keep_forever', 'editor', ]; /** * Prepare item before render. * * @param object $item The model item * * @return object * * @since 4.0.0 */ protected function prepareItem($item) { $item->id = $item->version_id; unset($item->version_id); $item->version_data = (array) json_decode($item->version_data, true); return parent::prepareItem($item); } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings