From 7a68b4b428b38f8ffd043338e842e42fd3a07d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Thu, 3 Jan 2019 00:10:48 +0100 Subject: [PATCH] Fix #771, add support for embeded pictures in XMPP forms --- app/widgets/Account/Account.php | 2 +- app/widgets/AccountNext/AccountNext.php | 10 +- app/widgets/AdHoc/AdHoc.php | 2 +- app/widgets/Chat/Chat.php | 2 +- .../CommunityConfig/CommunityConfig.php | 2 +- lib/XMPPtoForm.php | 153 ++++++++++-------- themes/material/css/form.css | 5 + 7 files changed, 95 insertions(+), 81 deletions(-) diff --git a/app/widgets/Account/Account.php b/app/widgets/Account/Account.php index 3735d94b5..95226e3ec 100644 --- a/app/widgets/Account/Account.php +++ b/app/widgets/Account/Account.php @@ -38,7 +38,7 @@ class Account extends \Movim\Widget\Base if (isset($content->x)) { $xml = new \XMPPtoForm; - $form = $xml->getHTML($content->x->asXML()); + $form = $xml->getHTML($content->x); $view->assign('form', $form); $view->assign('from', $package->from); diff --git a/app/widgets/AccountNext/AccountNext.php b/app/widgets/AccountNext/AccountNext.php index 4ad7a1266..ba58884e1 100644 --- a/app/widgets/AccountNext/AccountNext.php +++ b/app/widgets/AccountNext/AccountNext.php @@ -39,11 +39,8 @@ class AccountNext extends \Movim\Widget\Base switch($form->x->attributes()->xmlns) { case 'jabber:x:data' : $formview = $this->tpl(); - - $formh = $xtf->getHTML($form->x->asXML()); $formview->assign('submitdata', $this->call('ajaxRegister', "MovimUtils.formToJson('data')")); - - $formview->assign('formh', $formh); + $formview->assign('formh', $xtf->getHTML($form->x, $form)); $html = $formview->draw('_accountnext_form'); break; case 'jabber:x:oob' : @@ -52,11 +49,8 @@ class AccountNext extends \Movim\Widget\Base } } else { $formview = $this->tpl(); - - $formh = $xtf->getHTML($form->asXML()); $formview->assign('submitdata', $this->call('ajaxRegister', "MovimUtils.formToJson('data')")); - - $formview->assign('formh', $formh); + $formview->assign('formh', $xtf->getHTML($form)); $html = $formview->draw('_accountnext_form'); } diff --git a/app/widgets/AdHoc/AdHoc.php b/app/widgets/AdHoc/AdHoc.php index ee591f62a..198432a9d 100644 --- a/app/widgets/AdHoc/AdHoc.php +++ b/app/widgets/AdHoc/AdHoc.php @@ -40,7 +40,7 @@ class AdHoc extends \Movim\Widget\Base $this->rpc('AdHoc.initForm'); } elseif (isset($command->x)) { $xml = new \XMPPtoForm(); - $form = $xml->getHTML($command->x->asXML()); + $form = $xml->getHTML($command->x); $view->assign('form', $form); $view->assign('attributes', $command->attributes()); diff --git a/app/widgets/Chat/Chat.php b/app/widgets/Chat/Chat.php index 0b48d19f0..d556fa442 100644 --- a/app/widgets/Chat/Chat.php +++ b/app/widgets/Chat/Chat.php @@ -194,7 +194,7 @@ class Chat extends \Movim\Widget\Base $view = $this->tpl(); $xml = new \XMPPtoForm; - $form = $xml->getHTML($config->x->asXML()); + $form = $xml->getHTML($config->x); $view->assign('form', $form); $view->assign('room', $room); diff --git a/app/widgets/CommunityConfig/CommunityConfig.php b/app/widgets/CommunityConfig/CommunityConfig.php index 4f1fe3ae6..9b382eceb 100644 --- a/app/widgets/CommunityConfig/CommunityConfig.php +++ b/app/widgets/CommunityConfig/CommunityConfig.php @@ -22,7 +22,7 @@ class CommunityConfig extends Base $view = $this->tpl(); $xml = new \XMPPtoForm; - $form = $xml->getHTML($config->x->asXML()); + $form = $xml->getHTML($config->x); $view->assign('form', $form); $view->assign('server', $origin); diff --git a/lib/XMPPtoForm.php b/lib/XMPPtoForm.php index 60f0d1fe7..d98a40f3e 100644 --- a/lib/XMPPtoForm.php +++ b/lib/XMPPtoForm.php @@ -4,6 +4,7 @@ class XMPPtoForm { private $fieldset; private $xmpp; + private $stanza; private $html; public function __construct() @@ -13,11 +14,12 @@ class XMPPtoForm $this->xmpp = ''; } - public function getHTML($xmpp) + public function getHTML(\SimpleXMLElement $xmpp, $stanza = false) { - $this->setXMPP($xmpp); + $this->xmpp = $xmpp; + $this->stanza = $stanza; $this->create(); - return $this->html->saveXML(); + return $this->html->saveHTML(); } public function getArray($xmpp) @@ -31,75 +33,85 @@ class XMPPtoForm return $array; } - public function setXMPP($xmpp) - { - $this->xmpp = $xmpp; - } - public function create() { - $this->xmpp = str_replace('xmlns=', 'ns=', $this->xmpp); - $x = new SimpleXMLElement($this->xmpp); + //$this->xmpp = str_replace('xmlns=', 'ns=', $this->xmpp); + //$x = new SimpleXMLElement($this->xmpp); - foreach ($x->children() as $element) { + foreach ($this->xmpp->children() as $element) { + \Utils::debug($element->getName()); switch($element->getName()) { - case "title": + case 'title': $this->outTitle($element); break; - case "instructions": + case 'instructions': $this->outP($element); break; - case "field": - switch($element['type']) { - case "boolean": - $this->outCheckbox($element); - break; - //case "fixed": - // $this->outBold($element); - // break; - case "text-single": - $this->outInput($element, ""); - break; - case "text-multi": - $this->outTextarea($element); - break; - case "text-private": - $this->outInput($element, "password"); - break; - case "hidden": - $this->outHiddeninput($element); - break; - case "list-multi": - //$this->outList($element); - break; - case "list-single": - $this->outList($element); - break; - case "jid-multi": - $this->outInput($element, "email"); - break; - case "jid-single": - $this->outInput($element, "email"); - break; - case "fixed": - $this->outP((string)$element->value); - break; - default: - $this->outInput($element, "text"); - break; + case 'field': + if (isset($element->media) + && (string)$element->media->attributes()->xmlns == 'urn:xmpp:media-element' + && isset($element->media->uri)) { + $uri = parse_url($element->media->uri); + switch ($uri['scheme']) { + case 'cid': + foreach($this->stanza->xpath('//data[@cid=\''.$uri['path'].'\']') as $data) { + $this->outImage('data:'.$data->attributes()->type.';base64,'.(string)$data); + } + break; + case 'http': + case 'https': + $this->outImage($uri); + break; + } + } + + if(isset($element->attributes()->type)) { + switch($element->attributes()->type) { + case 'boolean': + $this->outCheckbox($element); + break; + case 'text-single': + $this->outInput($element, ''); + break; + case 'text-multi': + $this->outTextarea($element); + break; + case 'text-private': + $this->outInput($element, 'password'); + break; + case 'hidden': + $this->outHiddeninput($element); + break; + case 'list-multi': + //$this->outList($element); + break; + case 'list-single': + $this->outList($element); + break; + case 'jid-multi': + $this->outInput($element, 'email'); + break; + case 'jid-single': + $this->outInput($element, 'email'); + break; + case 'fixed': + $this->outP((string)$element->value); + break; + default: + $this->outInput($element, 'text'); + break; + } } break; case 'url': - break; - /*XML without element*/ case 'username': case 'email': case 'password': $this->outGeneric($element->getName()); break; default: - //$this->html .= ""; + //$this->html .= ''; } } } @@ -129,10 +141,21 @@ class XMPPtoForm $this->html->appendChild($title); } + private function outImage(string $src) + { + $div = $this->html->createElement('div'); + $img = $this->html->createElement('img'); + $img->setAttribute('src', $src); + $div->appendChild($img); + $this->html->appendChild($div); + } + private function outP($s) { - $title = $this->html->createElement('p', $s); - $this->html->appendChild($title); + $div = $this->html->createElement('div'); + $p = $this->html->createElement('p', $s); + $div->appendChild($p); + $this->html->appendChild($div); } private function outUrl($s) @@ -141,15 +164,7 @@ class XMPPtoForm $a->setAttribute('href', $s->getName()); $this->html->appendChild($a); } - /* - private function outBold($s) { - if ($this->fieldset > 0) { - $this->html .= ''; - } - $this->html .= '
'.$s->value.'
'; - $this->fieldset ++; - } - */ + private function outCheckbox($s) { $container = $this->html->createElement('div'); @@ -174,7 +189,7 @@ class XMPPtoForm $option = $this->html->createElement('option', __('button.bool_yes')); $option->setAttribute('value', 'true'); - if (isset($s->value) || $s->value == "true" || $s->value == "1") { + if (isset($s->value) || $s->value == 'true' || $s->value == '1') { $option->setAttribute('selected', 'selected'); } @@ -183,7 +198,7 @@ class XMPPtoForm $option = $this->html->createElement('option', __('button.bool_no')); $option->setAttribute('value', 'false'); - if (!isset($s->value) || $s->value == "false" || $s->value == "0") { + if (!isset($s->value) || $s->value == 'false' || $s->value == '0') { $option->setAttribute('selected', 'selected'); } @@ -211,7 +226,7 @@ class XMPPtoForm } foreach ($s->children() as $value) { - if ($value->getName() == "value") { + if ($value->getName() == 'value') { $textarea->nodeValue .= $value . "\n"; } } @@ -252,7 +267,7 @@ class XMPPtoForm } foreach ($s->children() as $value) { - if ($value->getName() == "value") { + if ($value->getName() == 'value') { $input->setAttribute('value', $value); } } diff --git a/themes/material/css/form.css b/themes/material/css/form.css index 50a099293..cf8157424 100644 --- a/themes/material/css/form.css +++ b/themes/material/css/form.css @@ -142,6 +142,11 @@ form > div > textarea { box-shadow: 0px 1px 0px rgba(var(--movim-font), 0.12); } +form > div > img, +form > div > p { + padding-top: 1.5rem; +} + form > div > .select { position: relative; padding-top: 4rem;