<?php
/**
 * @copyright Copyright (c) 2016, ownCloud, Inc.
 *
 * @author Bart Visscher <bartv@thisnet.nl>
 * @author Bernhard Posselt <dev@bernhard-posselt.com>
 * @author Christoph Wurst <christoph@owncloud.com>
 * @author Felix Moeller <mail@felixmoeller.de>
 * @author Georg Ehrke <georg@owncloud.com>
 * @author Lukas Reschke <lukas@statuscode.ch>
 * @author Morris Jobke <hey@morrisjobke.de>
 * @author Robin Appelman <robin@icewind.nl>
 * @author Thomas Müller <thomas.mueller@tmit.eu>
 * @author Thomas Tanghus <thomas@tanghus.net>
 * @author Vincent Petry <pvince81@owncloud.com>
 *
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

/**
 * Class OC_JSON
 * @deprecated Use a AppFramework JSONResponse instead
 */
class OC_JSON{
	static protected $send_content_type_header = false;
	/**
	 * set Content-Type header to jsonrequest
	 * @deprecated Use a AppFramework JSONResponse instead
	 */
	public static function setContentTypeHeader($type='application/json') {
		if (!self::$send_content_type_header) {
			// We send json data
			header( 'Content-Type: '.$type . '; charset=utf-8');
			self::$send_content_type_header = true;
		}
	}

	/**
	 * Check if the app is enabled, send json error msg if not
	 * @param string $app
	 * @deprecated Use the AppFramework instead. It will automatically check if the app is enabled.
	 * @suppress PhanDeprecatedFunction
	 */
	public static function checkAppEnabled($app) {
		if( !\OC::$server->getAppManager()->isEnabledForUser($app)) {
			$l = \OC::$server->getL10N('lib');
			self::error(array( 'data' => array( 'message' => $l->t('Application is not enabled'), 'error' => 'application_not_enabled' )));
			exit();
		}
	}

	/**
	 * Check if the user is logged in, send json error msg if not
	 * @deprecated Use annotation based ACLs from the AppFramework instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function checkLoggedIn() {
		$twoFactorAuthManger = \OC::$server->getTwoFactorAuthManager();
		if( !\OC::$server->getUserSession()->isLoggedIn()
			|| $twoFactorAuthManger->needsSecondFactor(\OC::$server->getUserSession()->getUser())) {
			$l = \OC::$server->getL10N('lib');
			http_response_code(\OCP\AppFramework\Http::STATUS_UNAUTHORIZED);
			self::error(array( 'data' => array( 'message' => $l->t('Authentication error'), 'error' => 'authentication_error' )));
			exit();
		}
	}

	/**
	 * Check an ajax get/post call if the request token is valid, send json error msg if not.
	 * @deprecated Use annotation based CSRF checks from the AppFramework instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function callCheck() {
		if(!\OC::$server->getRequest()->passesStrictCookieCheck()) {
			header('Location: '.\OC::$WEBROOT);
			exit();
		}

		if( !(\OC::$server->getRequest()->passesCSRFCheck())) {
			$l = \OC::$server->getL10N('lib');
			self::error(array( 'data' => array( 'message' => $l->t('Token expired. Please reload page.'), 'error' => 'token_expired' )));
			exit();
		}
	}

	/**
	 * Check if the user is a admin, send json error msg if not.
	 * @deprecated Use annotation based ACLs from the AppFramework instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function checkAdminUser() {
		if( !OC_User::isAdminUser(OC_User::getUser())) {
			$l = \OC::$server->getL10N('lib');
			self::error(array( 'data' => array( 'message' => $l->t('Authentication error'), 'error' => 'authentication_error' )));
			exit();
		}
	}

	/**
	 * Check is a given user exists - send json error msg if not
	 * @param string $user
	 * @deprecated Use a AppFramework JSONResponse instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function checkUserExists($user) {
		if (!OCP\User::userExists($user)) {
			$l = \OC::$server->getL10N('lib');
			OCP\JSON::error(array('data' => array('message' => $l->t('Unknown user'), 'error' => 'unknown_user' )));
			exit;
		}
	}


	/**
	 * Check if the user is a subadmin, send json error msg if not
	 * @deprecated Use annotation based ACLs from the AppFramework instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function checkSubAdminUser() {
		$userObject = \OC::$server->getUserSession()->getUser();
		$isSubAdmin = false;
		if($userObject !== null) {
			$isSubAdmin = \OC::$server->getGroupManager()->getSubAdmin()->isSubAdmin($userObject);
		}

		if(!$isSubAdmin) {
			$l = \OC::$server->getL10N('lib');
			self::error(array( 'data' => array( 'message' => $l->t('Authentication error'), 'error' => 'authentication_error' )));
			exit();
		}
	}

	/**
	 * Send json error msg
	 * @deprecated Use a AppFramework JSONResponse instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function error($data = array()) {
		$data['status'] = 'error';
		self::encodedPrint($data);
	}

	/**
	 * Send json success msg
	 * @deprecated Use a AppFramework JSONResponse instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function success($data = array()) {
		$data['status'] = 'success';
		self::encodedPrint($data);
	}

	/**
	 * Convert OC_L10N_String to string, for use in json encodings
	 */
	protected static function to_string(&$value) {
		if ($value instanceof \OC\L10N\L10NString) {
			$value = (string)$value;
		}
	}

	/**
	 * Encode and print $data in json format
	 * @deprecated Use a AppFramework JSONResponse instead
	 * @suppress PhanDeprecatedFunction
	 */
	public static function encodedPrint($data, $setContentType=true) {
		if($setContentType) {
			self::setContentTypeHeader();
		}
		echo self::encode($data);
	}

	/**
	 * Encode JSON
	 * @deprecated Use a AppFramework JSONResponse instead
	 */
	public static function encode($data) {
		if (is_array($data)) {
			array_walk_recursive($data, array('OC_JSON', 'to_string'));
		}
		return json_encode($data, JSON_HEX_TAG);
	}
}
work.git/about/?h=JS-RPC-docs-link-syntax'>about</a><a href='/vaadin-framework.git/?h=JS-RPC-docs-link-syntax'>summary</a><a href='/vaadin-framework.git/refs/?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>refs</a><a href='/vaadin-framework.git/log/documentation/gwt/gwt-advanced.asciidoc?h=JS-RPC-docs-link-syntax'>log</a><a class='active' href='/vaadin-framework.git/tree/documentation/gwt/gwt-advanced.asciidoc?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>tree</a><a href='/vaadin-framework.git/commit/documentation/gwt/gwt-advanced.asciidoc?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>commit</a><a href='/vaadin-framework.git/diff/documentation/gwt/gwt-advanced.asciidoc?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>diff</a><a href='/vaadin-framework.git/stats/documentation/gwt/gwt-advanced.asciidoc?h=JS-RPC-docs-link-syntax'>stats</a></td><td class='form'><form class='right' method='get' action='/vaadin-framework.git/log/documentation/gwt/gwt-advanced.asciidoc'>
<input type='hidden' name='h' value='JS-RPC-docs-link-syntax'/><input type='hidden' name='id' value='cca89c574379d350fa0715a42eceb988b5c8b3f5'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/vaadin-framework.git/tree/?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>root</a>/<a href='/vaadin-framework.git/tree/documentation?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>documentation</a>/<a href='/vaadin-framework.git/tree/documentation/gwt?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>gwt</a>/<a href='/vaadin-framework.git/tree/documentation/gwt/gwt-advanced.asciidoc?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>gwt-advanced.asciidoc</a></div><div class='content'>blob: f6991ef0e1abf31140e39d715c67b59d6d3b2a0c (<a href='/vaadin-framework.git/plain/documentation/gwt/gwt-advanced.asciidoc?h=JS-RPC-docs-link-syntax&amp;id=cca89c574379d350fa0715a42eceb988b5c8b3f5'>plain</a>)
<table summary='blob content' class='blob'>
<tr><td class='linenumbers'><pre><a id='n1' href='#n1'>1</a>
<a id='n2' href='#n2'>2</a>
<a id='n3' href='#n3'>3</a>
<a id='n4' href='#n4'>4</a>
<a id='n5' href='#n5'>5</a>
<a id='n6' href='#n6'>6</a>
<a id='n7' href='#n7'>7</a>
<a id='n8' href='#n8'>8</a>
<a id='n9' href='#n9'>9</a>
<a id='n10' href='#n10'>10</a>
<a id='n11' href='#n11'>11</a>
<a id='n12' href='#n12'>12</a>
<a id='n13' href='#n13'>13</a>
<a id='n14' href='#n14'>14</a>
<a id='n15' href='#n15'>15</a>
<a id='n16' href='#n16'>16</a>
<a id='n17' href='#n17'>17</a>
<a id='n18' href='#n18'>18</a>
<a id='n19' href='#n19'>19</a>
<a id='n20' href='#n20'>20</a>
<a id='n21' href='#n21'>21</a>
<a id='n22' href='#n22'>22</a>
<a id='n23' href='#n23'>23</a>
<a id='n24' href='#n24'>24</a>
<a id='n25' href='#n25'>25</a>
<a id='n26' href='#n26'>26</a>
<a id='n27' href='#n27'>27</a>
<a id='n28' href='#n28'>28</a>
<a id='n29' href='#n29'>29</a>
<a id='n30' href='#n30'>30</a>
<a id='n31' href='#n31'>31</a>
<a id='n32' href='#n32'>32</a>
<a id='n33' href='#n33'>33</a>
<a id='n34' href='#n34'>34</a>
<a id='n35' href='#n35'>35</a>
<a id='n36' href='#n36'>36</a>
<a id='n37' href='#n37'>37</a>
<a id='n38' href='#n38'>38</a>
<a id='n39' href='#n39'>39</a>
<a id='n40' href='#n40'>40</a>
<a id='n41' href='#n41'>41</a>
<a id='n42' href='#n42'>42</a>
<a id='n43' href='#n43'>43</a>
<a id='n44' href='#n44'>44</a>
<a id='n45' href='#n45'>45</a>
<a id='n46' href='#n46'>46</a>
<a id='n47' href='#n47'>47</a>
<a id='n48' href='#n48'>48</a>
<a id='n49' href='#n49'>49</a>
<a id='n50' href='#n50'>50</a>
<a id='n51' href='#n51'>51</a>
<a id='n52' href='#n52'>52</a>
<a id='n53' href='#n53'>53</a>
<a id='n54' href='#n54'>54</a>
<a id='n55' href='#n55'>55</a>
<a id='n56' href='#n56'>56</a>
<a id='n57' href='#n57'>57</a>
<a id='n58' href='#n58'>58</a>
<a id='n59' href='#n59'>59</a>
<a id='n60' href='#n60'>60</a>
</pre></td>
<td class='lines'><pre><code><style>pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span>---
title: Advanced Client-Side Topics
order: 10
layout: page
---

[[gwt.advanced]]
= Advanced Client-Side Topics

In the following, we mention some topics that you may encounter when integrating
widgets.

[[gwt.advanced.phases]]
== Client-Side Processing Phases

Vaadin&#39;s client-side engine reacts to changes from the server in a number of
phases, the order of which can be relevant for a connector. The processing
occurs in the [methodname]#handleUIDLMessage()# method in
[classname]#ApplicationConnection#, but the logic can be quite overwhelming, so
we describe the phases in the following summary.

. Any dependencies defined by using [classname]#@JavaScript#,
[classname]#@StyleSheet# or [classname]#@HtmlImport# on the server-side class
are loaded. Processing does not continue until the browser confirms that they
have been loaded.

. New connectors are instantiated and [methodname]#init()# is run for each
[interfacename]#Connector#.

. State objects are updated, but no state change event is fired yet.

. The connector hierarchy is updated, but no hierarchy change event is fired yet.
[methodname]#setParent()# and [methodname]#setChildren()# are run in this phase.

. Hierarchy change events are fired. This means that all state objects and the
entire hierarchy are already up to date when this happens. The DOM hierarchy
should in theory be up to date after all hierarchy events have been handled,
although there are some built-in components that for various reasons do not
always live up to this promise.

. Captions are updated, causing [methodname]#updateCaption()# to be invoked on
layouts as needed.

. [classname]#@DelegateToWidget# is handled for all changed state objects using
the annotation.

. State change events are fired for all changed state objects.

. [methodname]#updateFromUIDL()# is called for legacy connectors.

. All RPC methods received from the server are invoked.

. Connectors that are no longer included in the hierarchy are unregistered. This
calls [methodname]#onUnregister()# on the [interfacename]#Connector#.

. The layout phase starts, first checking the sizes and positions of all elements,
and then notifying any [interfacename]#ElementResizeListener#s, as well as
calling the appropriate layout method for the connectors that implement either
[classname]#SimpleManagedLayout# or [classname]#DirectionalManagedLayout#
interface.
</pre></div>
</code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.3</a> (<a href='https://git-scm.com/'>git 2.39.1</a>) at 2025-07-31 19:03:56 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>
