    public function searchNew() {
        global $db, $user;
        //$this->params['query'] = str_ireplace('-','\-',$this->params['query']);
        $sql = "select DISTINCT(p.id) as id, p.title, model, sef_url, f.id as fileid, ";
        $sql .= "match (p.title,p.model,p.body) against ('" . $this->params['query'] . "*' IN BOOLEAN MODE) as relevance, ";
        $sql .= "CASE when p.model like '" . $this->params['query'] . "%' then 1 else 0 END as modelmatch, ";
        $sql .= "CASE when p.title like '%" . $this->params['query'] . "%' then 1 else 0 END as titlematch ";
        $sql .= "from " . $db->prefix . "product as p INNER JOIN " .
            $db->prefix . "content_expFiles as cef ON p.id=cef.content_id AND cef.content_type IN ('product','eventregistration','donation','giftcard') AND cef.subtype='mainimage'  INNER JOIN " . $db->prefix .
            "expFiles as f ON cef.expFiles_id = f.id WHERE ";
        if (!$user->isAdmin()) $sql .= '(p.active_type=0 OR p.active_type=1) AND ';
        $sql .= " match (p.title,p.model,p.body) against ('" . $this->params['query'] . "*' IN BOOLEAN MODE) AND p.parent_id=0 ";
        $sql .= " HAVING relevance > 0 ";
        //$sql .= "GROUP BY p.id ";
        $sql .= "order by modelmatch,titlematch,relevance desc LIMIT 10";

        eDebug($sql);
        $res = $db->selectObjectsBySql($sql);
        eDebug($res, true);
        $ar = new expAjaxReply(200, gt('Here\'s the items you wanted'), $res);
        $ar->send();
    }


		    $controller = new $ctlname();
		    if (method_exists($controller,'isSearchable') && $controller->isSearchable()) {
//			    $mods[$controller->name()] = $controller->addContentToSearch();
                $mods[$controller->searchName()] = $controller->addContentToSearch();
		    }
	    }

	    uksort($mods,'strnatcasecmp');
	    assign_to_template(array(
            'mods'=>$mods
        ));
    }


    function updateObject($object, $table, $where=null, $identifier='id', $is_revisioned=false) {

        if ($is_revisioned) {
            $object->revision_id++;
            //if ($table=="text") eDebug($object);
            $res = $this->insertObject($object, $table);
            //if ($table=="text") eDebug($object,true);
            $this->trim_revisions($table, $object->$identifier, WORKFLOW_REVISION_LIMIT);
            return $res;
        }
        $sql = "UPDATE " . $this->prefix . "$table SET ";
        foreach (get_object_vars($object) as $var => $val) {
            //We do not want to save any fields that start with an '_'
            //if($is_revisioned && $var=='revision_id') $val++;
            if ($var{0} != '_') {
                if (is_array($val) || is_object($val)) {
                    $val = serialize($val);
                    $sql .= "`$var`='".$val."',";
                } else {
                    $sql .= "`$var`='" . $this->escapeString($val) . "',";
                }
            }
        }
        $sql = substr($sql, 0, -1) . " WHERE ";
        if ($where != null)
            $sql .= $this->injectProof($where);
        else
            $sql .= "`" . $identifier . "`=" . $object->$identifier;
        //if ($table == 'text') eDebug($sql,true);
        $res = (@mysqli_query($this->connection, $sql) != false);
        return $res;
    }


    protected function setUp()
    {
        $this->originalTrustedHeaderName = Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP);
    }


    function addDiscountToCart() {
//        global $user, $order;
        global $order;
        //lookup discount to see if it's real and valid, and not already in our cart
        //this will change once we allow more than one coupon code

        $discount = new discounts();
        $discount = $discount->getCouponByName($this->params['coupon_code']);

        if (empty($discount)) {
            flash('error', gt("This discount code you entered does not exist."));
            //redirect_to(array('controller'=>'cart', 'action'=>'checkout'));
            expHistory::back();
        }

        //check to see if it's in our cart already
        if ($this->isDiscountInCart($discount->id)) {
            flash('error', gt("This discount code is already in your cart."));
            //redirect_to(array('controller'=>'cart', 'action'=>'checkout'));
            expHistory::back();
        }

        //this should really be reworked, as it shoudn't redirect directly and not return
        $validateDiscountMessage = $discount->validateDiscount();
        if ($validateDiscountMessage == "") {
            //if all good, add to cart, otherwise it will have redirected
            $od               = new order_discounts();
            $od->orders_id    = $order->id;
            $od->discounts_id = $discount->id;
            $od->coupon_code  = $discount->coupon_code;
            $od->title        = $discount->title;
            $od->body         = $discount->body;
            $od->save();
            // set this to just the discount applied via this coupon?? if so, when though? $od->discount_total = ??;
            flash('message', gt("The discount code has been applied to your cart."));
        } else {
            flash('error', $validateDiscountMessage);
        }
        //redirect_to(array('controller'=>'cart', 'action'=>'checkout'));
        expHistory::back();
    }


    public function editAlt() {
        global $user;
        $file = new expFile($this->params['id']);
        if ($user->id==$file->poster || $user->isAdmin()) {
            $file->alt = $this->params['newValue'];
            $file->save();
            $ar = new expAjaxReply(200, gt('Your alt was updated successfully'), $file);
        } else {
            $ar = new expAjaxReply(300, gt("You didn't create this file, so you can't edit it."));
        }
        $ar->send();
        echo json_encode($file);  //FIXME we exit before hitting this
    }


    public function manage_sitemap() {
        global $db, $user, $sectionObj, $sections;

        expHistory::set('viewable', $this->params);
        $id      = $sectionObj->id;
        $current = null;
        // all we need to do is determine the current section
        $navsections = $sections;
        if ($sectionObj->parent == -1) {
            $current = $sectionObj;
        } else {
            foreach ($navsections as $section) {
                if ($section->id == $id) {
                    $current = $section;
                    break;
                }
            }
        }
        assign_to_template(array(
            'sasections'   => $db->selectObjects('section', 'parent=-1'),
            'sections'     => $navsections,
            'current'      => $current,
            'canManage'    => ((isset($user->is_acting_admin) && $user->is_acting_admin == 1) ? 1 : 0),
        ));
    }


				} elseif ( $sSecLabel[0] == '{' ) {
					// Uses LST::includeTemplate() from LabeledSectionTransclusion extension to include templates from the page
					// primary syntax {template}suffix
					$template1 = trim( substr( $sSecLabel, 1, strpos( $sSecLabel, '}' ) - 1 ) );
					$template2 = trim( str_replace( '}', '', substr( $sSecLabel, 1 ) ) );
					// alternate syntax: {template|surrogate}
					if ( $template2 == $template1 && strpos( $template1, '|' ) > 0 ) {
						$template1 = preg_replace( '/\|.*/', '', $template1 );
						$template2 = preg_replace( '/^.+\|/', '', $template2 );
					}
					//Why the hell was defaultTemplateSuffix be passed all over the place for just fucking here?  --Alexia
					$secPieces    = LST::includeTemplate( $this->parser, $this, $s, $article, $template1, $template2, $template2 . $this->getTemplateSuffix(), $mustMatch, $mustNotMatch, $this->includePageParsed, implode( ', ', $article->mCategoryLinks ) );
					$secPiece[$s] = implode( isset( $this->multiSectionSeparators[$s] ) ? $this->replaceTagCount( $this->multiSectionSeparators[$s], $filteredCount ) : '', $secPieces );
					if ( $this->getDominantSectionCount() >= 0 && $s == $this->getDominantSectionCount() && count( $secPieces ) > 1 ) {
						$dominantPieces = $secPieces;
					}
					if ( ( $mustMatch != '' || $mustNotMatch != '' ) && count( $secPieces ) <= 1 && $secPieces[0] == '' ) {
						$matchFailed = true; // NOTHING MATCHED
						break;
					}
				} else {


	private function setDefaults() {
		$this->setParameter( 'defaulttemplatesuffix', '.default' );

		$parameters = $this->getParametersForRichness();
		foreach ( $parameters as $parameter ) {
			if ( $this->getData( $parameter )['default'] !== null && !( $this->getData( $parameter )['default'] === false && $this->getData( $parameter )['boolean'] === true ) ) {
				if ( $parameter == 'debug' ) {
					\DynamicPageListHooks::setDebugLevel( $this->getData( $parameter )['default'] );
				}
				$this->setParameter( $parameter, $this->getData( $parameter )['default'] );
			}
		}
	}


	function __construct() {
		parent::__construct( 'GlobalNewFiles' );
	}


    public function delete() {
        global $db, $history;

        /* The global constants can be overriden by passing appropriate params */
        //sure wish I could do this once in the constructor. sadly $this->params[] isn't set yet
        $require_login = empty($this->params['require_login']) ? SIMPLENOTE_REQUIRE_LOGIN : $this->params['require_login'];
        $require_approval = empty($this->params['require_approval']) ? SIMPLENOTE_REQUIRE_APPROVAL : $this->params['require_approval'];
        $require_notification = empty($this->params['require_notification']) ? SIMPLENOTE_REQUIRE_NOTIFICATION : $this->params['require_notification'];
        $notification_email = empty($this->params['notification_email']) ? SIMPLENOTE_NOTIFICATION_EMAIL : $this->params['notification_email'];

        if (empty($this->params['id'])) {
            flash('error', gt('Missing id for the comment you would like to delete'));
            $lastUrl = expHistory::getLast('editable');
        }

        // delete the note
        $simplenote = new expSimpleNote($this->params['id']);
        $rows = $simplenote->delete();

        // delete the assocication too
        $db->delete($simplenote->attachable_table, 'expsimplenote_id='.$this->params['id']);

        // send the user back where they came from.
        $lastUrl = expHistory::getLast('editable');
        if (!empty($this->params['tab']))
        {
            $lastUrl .= "#".$this->params['tab'];
        }
        redirect_to($lastUrl);
    }


	public function manage_versions() {
	    expHistory::set('manageable', $this->params);

	    $hv = new help_version();
	    $current_version = $hv->find('first', 'is_current=1');

	    $sql  = 'SELECT hv.*, COUNT(h.title) AS num_docs FROM '.DB_TABLE_PREFIX.'_help h ';
	    $sql .= 'RIGHT JOIN '.DB_TABLE_PREFIX.'_help_version hv ON h.help_version_id=hv.id GROUP BY hv.version';

	    $page = new expPaginator(array(
            'sql'=>$sql,
            'limit'=>30,
            'order'      => (isset($this->params['order']) ? $this->params['order'] : 'version'),
            'dir'        => (isset($this->params['dir']) ? $this->params['dir'] : 'DESC'),
            'page'=>(isset($this->params['page']) ? $this->params['page'] : 1),
            'controller'=>$this->baseclassname,
            'action'=>$this->params['action'],
            'src'=>$this->loc->src,
            'columns'=>array(
                gt('Version')=>'version',
                gt('Title')=>'title',
                gt('Current')=>'is_current',
                gt('# of Docs')=>'num_docs'
            ),
        ));

	    assign_to_template(array(
            'current_version'=>$current_version,
            'page'=>$page
        ));
	}


    function productFeed() {
//        global $db;
        //check query password to avoid DDOS
        /*
            * condition  = new
            * description
            * id - SKU
            * link
            * price
            * title
            * brand - manufacturer
            * image link - fullsized image, up to 10, comma seperated
            * product type - category - "Electronics > Audio > Audio Accessories MP3 Player Accessories","Health & Beauty > Healthcare > Biometric Monitors > Pedometers"
         */
        $out = '"id","condition","description","like","price","title","brand","image link","product type"' . chr(13) . chr(10);

        $p = new product();
        $prods = $p->find('all', 'parent_id=0 AND ');
        //$prods =  $db->selectObjects('product','parent_id=0 AND');
    }


    public function getCompiledPath($path)
    {
        return $this->cachePath.'/'.sha1($path).'.php';
    }


fwrite(STDERR, sprintf("%2d %s ==> %s\n", $i + 1, $test, var_export($result, true)));


	public function loginForm( WebRequest $request ) { // Step 13
		$out = $this->getOutput();
		$username = $request->getVal('username');
		$codes = SOA2Login::codes( $username );
		$out->addHTML(Html::openElement('form', [ 'method' => 'POST' ]));
		$out->addHTML(Html::hidden('username', $username));
		$out->addHTML(Html::hidden('token', $codes['csrf'])); // Step 14
		$profile = Html::element(
			'a',
			[
				'href' => sprintf(SOA2_PROFILE_URL, urlencode($username)),
				'target' => '_new'
			],
			wfMessage('soa2-your-profile')->plain()
		);
		// Step 16
		$out->addHTML(Html::rawElement(
			'p', [],
			wfMessage('soa2-vercode-explanation')->rawParams($profile)->parse()
		));
		$out->addHTML(Html::rawElement('p', [], Html::element(
			'code', [], $codes['code']
		)));
		$out->addHTML(Html::rawElement('p', [], Html::submitButton(
			wfMessage('soa2-login')->plain(), []
		)));
		$out->addHTML(Html::closeElement('form'));
	}


    private function decryptContentEncryptionKey($private_key_or_secret) {
        switch ($this->header['alg']) {
            case 'RSA1_5':
                $rsa = $this->rsa($private_key_or_secret, RSA::ENCRYPTION_PKCS1);
                $this->content_encryption_key = $rsa->decrypt($this->jwe_encrypted_key);
                break;
            case 'RSA-OAEP':
                $rsa = $this->rsa($private_key_or_secret, RSA::ENCRYPTION_OAEP);
                $this->content_encryption_key = $rsa->decrypt($this->jwe_encrypted_key);
                break;
            case 'dir':
                $this->content_encryption_key = $private_key_or_secret;
                break;
            case 'A128KW':
            case 'A256KW':
            case 'ECDH-ES':
            case 'ECDH-ES+A128KW':
            case 'ECDH-ES+A256KW':
                throw new JOSE_Exception_UnexpectedAlgorithm('Algorithm not supported');
            default:
                throw new JOSE_Exception_UnexpectedAlgorithm('Unknown algorithm');
        }
        if (!$this->content_encryption_key) {
            # NOTE:
            #  Not to disclose timing difference between CEK decryption error and others.
            #  Mitigating Bleichenbacher Attack on PKCS#1 v1.5
            #  ref.) http://inaz2.hatenablog.com/entry/2016/01/26/222303
            $this->generateContentEncryptionKey(null);
        }
    }


  public function AddCC($address, $name = '') {
    return $this->AddAnAddress('cc', $address, $name);
  }


    public function update_discount() {
        $id = empty($this->params['id']) ? null : $this->params['id'];
        $discount = new discounts($id);
        // find required shipping method if needed
        if ($this->params['required_shipping_calculator_id'] > 0) {
            $this->params['required_shipping_method'] = $this->params['required_shipping_methods'][$this->params['required_shipping_calculator_id']];
        } else {
            $this->params['required_shipping_calculator_id'] = 0;
        }

        $discount->update($this->params);
        expHistory::back();
    }


    public function theme_switch() {
        if (!expUtil::isReallyWritable(BASE.'framework/conf/config.php')) {  // we can't write to the config.php file
            flash('error',gt('The file /framework/conf/config.php is NOT Writeable. You will be unable to change the theme.'));
        }
    	expSettings::change('DISPLAY_THEME_REAL', $this->params['theme']);
	    expSession::set('display_theme',$this->params['theme']);
	    $sv = isset($this->params['sv'])?$this->params['sv']:'';
	    if (strtolower($sv)=='default') {
	       $sv = '';
	    }
	    expSettings::change('THEME_STYLE_REAL',$sv);
	    expSession::set('theme_style',$sv);
	    expDatabase::install_dbtables();  // update tables to include any custom definitions in the new theme

        // $message = (MINIFY != 1) ? "Exponent is now minifying Javascript and CSS" : "Exponent is no longer minifying Javascript and CSS" ;
        // flash('message',$message);
	    $message = gt("You have selected the")." '".$this->params['theme']."' ".gt("theme");
	    if ($sv != '') {
		    $message .= ' '.gt('with').' '.$this->params['sv'].' '.gt('style variation');
	    }
	    flash('message',$message);
//        expSession::un_set('framework');
        expSession::set('force_less_compile', 1);
//        expTheme::removeSmartyCache();
        expSession::clearAllUsersSessionCache();
    	expHistory::returnTo('manageable');
    }


    public function chmod() {
        if (!AuthUser::hasPermission('file_manager_chmod')) {
            Flash::set('error', __('You do not have sufficient permissions to change the permissions on a file or directory.'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        // CSRF checks
        if (isset($_POST['csrf_token'])) {
            $csrf_token = $_POST['csrf_token'];
            if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/chmod')) {
                Flash::set('error', __('Invalid CSRF token found!'));
                redirect(get_url('plugin/file_manager/browse/'));
            }
        }
        else {
            Flash::set('error', __('No CSRF token found!'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        $data = $_POST['file'];
        $data['name'] = str_replace('..', '', $data['name']);
        $file = FILES_DIR . '/' . $data['name'];

        if (file_exists($file)) {
            if (@!chmod($file, octdec($data['mode'])))
                Flash::set('error', __('Permission denied!'));
        }
        else {
            Flash::set('error', __('File or directory not found!'));
        }

        $path = substr($data['name'], 0, strrpos($data['name'], '/'));
        redirect(get_url('plugin/file_manager/browse/' . $path));
    }


    function insertObject($object, $table) {
        //if ($table=="text") eDebug($object,true);
        $sql = "INSERT INTO `" . $this->prefix . "$table` (";
        $values = ") VALUES (";
        foreach (get_object_vars($object) as $var => $val) {
            //We do not want to save any fields that start with an '_'
            if ($var{0} != '_') {
                $sql .= "`$var`,";
                if ($values != ") VALUES (") {
                    $values .= ",";
                }
                $values .= "'" . $this->escapeString($val) . "'";
            }
        }
        $sql = substr($sql, 0, -1) . substr($values, 0) . ")";
        //if($table=='text')eDebug($sql,true);
        if (@mysqli_query($this->connection, $sql) != false) {
            $id = mysqli_insert_id($this->connection);
            return $id;
        } else
            return 0;
    }


    public function params()
    {
        $project = $this->getProject();
        $values = $this->request->getValues();

        if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
            $this->create();
            return;
        }

        $action = $this->actionManager->getAction($values['action_name']);
        $action_params = $action->getActionRequiredParameters();

        if (empty($action_params)) {
            $this->doCreation($project, $values + array('params' => array()));
        }

        $projects_list = $this->projectUserRoleModel->getActiveProjectsByUser($this->userSession->getId());
        unset($projects_list[$project['id']]);

        $this->response->html($this->template->render('action_creation/params', array(
            'values' => $values,
            'action_params' => $action_params,
            'columns_list' => $this->columnModel->getList($project['id']),
            'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id']),
            'projects_list' => $projects_list,
            'colors_list' => $this->colorModel->getList(),
            'categories_list' => $this->categoryModel->getList($project['id']),
            'links_list' => $this->linkModel->getList(0, false),
            'priorities_list' => $this->projectTaskPriorityModel->getPriorities($project),
            'project' => $project,
            'available_actions' => $this->actionManager->getAvailableActions(),
            'swimlane_list' => $this->swimlaneModel->getList($project['id']),
            'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
        )));
    }


    protected function setUp()
    {
        static::$functions = [];
        static::$fopen = null;
        static::$fread = null;
        parent::setUp();
        $this->security = new ExposedSecurity();
        $this->security->derivationIterations = 1000; // speed up test running
    }


    protected function forceChangePassword()
    {
        if (!Yii::$app->user->isMustChangePasswordUrl()) {
            return Yii::$app->getResponse()->redirect(Url::toRoute(Yii::$app->user->mustChangePasswordRoute));
        }
    }


   public function testGetDropdownValue($params, $expected, $session_params = []) {
      $this->login();

      $bkp_params = [];
      //set session params if any
      if (count($session_params)) {
         foreach ($session_params as $param => $value) {
            if (isset($_SESSION[$param])) {
               $bkp_params[$param] = $_SESSION[$param];
            }
            $_SESSION[$param] = $value;
         }
      }

      $params['_idor_token'] = \Session::getNewIDORToken($params['itemtype'] ?? '');

      $result = \Dropdown::getDropdownValue($params, false);

      //reset session params before executing test
      if (count($session_params)) {
         foreach ($session_params as $param => $value) {
            if (isset($bkp_params[$param])) {
               $_SESSION[$param] = $bkp_params[$param];
            } else {
               unset($_SESSION[$param]);
            }
         }
      }

      $this->array($result)->isIdenticalTo($expected);
   }


    function showByModel() {
        global $order, $template, $db;

        expHistory::set('viewable', $this->params);
        $product = new product();
        $model = $product->find("first", 'model="' . $this->params['model'] . '"');
        //eDebug($model);
        $product_type = new $model->product_type($model->id);
        //eDebug($product_type);
        $tpl = $product_type->getForm('show');
        if (!empty($tpl)) $template = new controllertemplate($this, $tpl);
        //eDebug($template);
        $this->grabConfig(); // grab the global config
        assign_to_template(array(
            'config'        => $this->config,
            'product'       => $product_type,
            'last_category' => $order->lastcat
        ));
    }


	public function setItemAttributes( $attributes ) {
		$this->itemAttributes = \Sanitizer::fixTagAttributes( $attributes, 'li' );
	}


    function categoryBreadcrumb() {
//        global $db, $router;

        //eDebug($this->category);

        /*if(isset($router->params['action']))
        {
            $ancestors = $this->category->pathToNode();
        }else if(isset($router->params['section']))
        {
            $current = $db->selectObject('section',' id= '.$router->params['section']);
            $ancestors[] = $current;
            if( $current->parent != -1 || $current->parent != 0 )
            {
                while ($db->selectObject('section',' id= '.$router->params['section']);)
                    if ($section->id == $id) {
                        $current = $section;
                        break;
                    }
                }
            }
            eDebug($sections);
            $ancestors = $this->category->pathToNode();
        }*/

        $ancestors = $this->category->pathToNode();
        // eDebug($ancestors);
        assign_to_template(array(
            'ancestors' => $ancestors
        ));
    }


            $db->insertObject($obj, 'expeAlerts_subscribers');
        }

        $count = count($this->params['ealerts']);

        if ($count > 0) {
            flash('message', gt("Your subscriptions have been updated.  You are now subscriber to")." ".$count.' '.gt('E-Alerts.'));
        } else {
            flash('error', gt("You have been unsubscribed from all E-Alerts."));
        }

        expHistory::back();
    }


			foreach($paths as $path)
			{
				// Convert wild-cards to RegEx
				$path = str_replace(array(':any', '*'), '.*', str_replace(':num', '[0-9]+', $path));

				// Does the RegEx match?
				if (!empty($_SERVER['HTTP_HOST']) AND preg_match('#^'.$path.'$#', $_SERVER['HTTP_HOST']))
				{
					define('ENVIRONMENT', $env);
					break 2;
				}
			}


    public function checkRedirect(RequestInterface $request, array $options, ResponseInterface $response)
    {
        if (\strpos((string) $response->getStatusCode(), '3') !== 0
            || !$response->hasHeader('Location')
        ) {
            return $response;
        }

        $this->guardMax($request, $response, $options);
        $nextRequest = $this->modifyRequest($request, $options, $response);

        // If authorization is handled by curl, unset it if host is different.
        if ($request->getUri()->getHost() !== $nextRequest->getUri()->getHost()
            && defined('\CURLOPT_HTTPAUTH')
        ) {
            unset(
                $options['curl'][\CURLOPT_HTTPAUTH],
                $options['curl'][\CURLOPT_USERPWD]
            );
        }

        if (isset($options['allow_redirects']['on_redirect'])) {
            ($options['allow_redirects']['on_redirect'])(
                $request,
                $response,
                $nextRequest->getUri()
            );
        }

        $promise = $this($nextRequest, $options);

        // Add headers to be able to track history of redirects.
        if (!empty($options['allow_redirects']['track_redirects'])) {
            return $this->withTracking(
                $promise,
                (string) $nextRequest->getUri(),
                $response->getStatusCode()
            );
        }

        return $promise;
    }


	private function _allrevisionsbefore( $option ) {
		$this->addTable( 'revision_actor_temp', 'rev' );
		$this->addSelect(
			[
				'rev.revactor_rev',
				'rev.revactor_timestamp'
			]
		);
		$this->addOrderBy( 'rev.revactor_rev' );
		$this->setOrderDir( 'DESC' );
		$this->addWhere(
			[
				$this->tableNames['page'] . '.page_id = rev.revactor_page',
				'rev.revactor_timestamp < ' . $this->convertTimestamp( $option )
			]
		);
	}


			$eml->prepareBody();
		}

        list ($success, $message) = $this->checkDoNotEmailFields ($eml);
        if (!$success) {
            return array ($success, $message);
        }

		$result = $eml->send($historyFlag);
		if (isset($result['code']) && $result['code'] == 200) {
            if (YII_UNIT_TESTING) {
                return array(true, $eml->message);
            } else {
                return array(true, "");
            }
        } else {
            return array (false, Yii::t('app', "Email could not be sent"));
        }
	}


    public function search(){
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;
        $username = Yii::app()->user->name;
        $criteria->addCondition("uploadedBy='$username' OR private=0 OR private=null");
        $criteria->addCondition("associationType != 'theme'");
        return $this->searchBase($criteria);
    }


                $chats[$index]->link = erLhcoreClassXMP::getBaseHost() . $_SERVER['HTTP_HOST'] . erLhcoreClassDesign::baseurl('user/login').'/(r)/'.rawurlencode(base64_encode('chat/single/'.$chat->id));
            }
        }


static function isSearchable() { return true; }


function XMLRPCremoveResourceGroupPriv($name, $type, $nodeid, $permissions){
    require_once(".ht-inc/privileges.php");
    global $user;

    if(! checkUserHasPriv("resourceGrant", $user['id'], $nodeid)){
        return array('status' => 'error',
                     'errorcode' => 53,
                     'errormsg' => 'Unable to remove group privileges on this node');
    }
    if($typeid = getResourceTypeID($type)){
        if(!checkForGroupName($name, 'resource', '', $typeid)){
            return array('status' => 'error',
                         'errorcode' => 28,
                         'errormsg' => 'resource group does not exist');
        }
        $perms = explode(':', $permissions);
        updateResourcePrivs("$type/$name", $nodeid, array(), $perms);
        return array('status' => 'success');
    } else {
        return array('status' => 'error',
                     'errorcode' => 56,
                     'errormsg' => 'Invalid resource type');
    }
}


$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn];


    private function generateFakeFileData()
    {
        return [
            'name' => md5(mt_rand()),
            'tmp_name' => md5(mt_rand()),
            'type' => 'image/jpeg',
            'size' => mt_rand(1000, 10000),
            'error' => '0',
        ];
    }


        foreach ($nodes as $node) {
            if ((($perm == 'view' && $node->public == 1) || expPermissions::check($perm, expCore::makeLocation('navigation', '', $node->id))) && !in_array($node->id, $ignore_ids)) {
                if ($node->active == 1) {
                    $text = str_pad('', ($depth + ($full ? 1 : 0)) * 3, '.', STR_PAD_LEFT) . $node->name;
                } else {
                    $text = str_pad('', ($depth + ($full ? 1 : 0)) * 3, '.', STR_PAD_LEFT) . '(' . $node->name . ')';
                }
                $ar[$node->id] = $text;
                foreach (self::levelDropdownControlArray($node->id, $depth + 1, $ignore_ids, $full, $perm, $addstandalones, $addinternalalias) as $id => $text) {
                    $ar[$id] = $text;
                }
            }
        }


    public static function hasChildren($i) {
        global $sections;

        if (($i + 1) >= count($sections)) return false;
        return ($sections[$i]->depth < $sections[$i + 1]->depth) ? true : false;
    }


    public function chmod() {
        if (!AuthUser::hasPermission('file_manager_chmod')) {
            Flash::set('error', __('You do not have sufficient permissions to change the permissions on a file or directory.'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        // CSRF checks
        if (isset($_POST['csrf_token'])) {
            $csrf_token = $_POST['csrf_token'];
            if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/chmod')) {
                Flash::set('error', __('Invalid CSRF token found!'));
                redirect(get_url('plugin/file_manager/browse/'));
            }
        }
        else {
            Flash::set('error', __('No CSRF token found!'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        $data = $_POST['file'];
        $data['name'] = str_replace('..', '', $data['name']);
        $file = FILES_DIR . '/' . $data['name'];

        if (file_exists($file)) {
            if (@!chmod($file, octdec($data['mode'])))
                Flash::set('error', __('Permission denied!'));
        }
        else {
            Flash::set('error', __('File or directory not found!'));
        }

        $path = substr($data['name'], 0, strrpos($data['name'], '/'));
        redirect(get_url('plugin/file_manager/browse/' . $path));
    }


    public function settings() {
        AuthUser::load();
        if (!AuthUser::isLoggedIn()) {
            redirect(get_url('login'));
        } else if (!AuthUser::hasPermission('admin_edit')) {
            Flash::set('error', __('You do not have permission to access the requested page!'));
            redirect(get_url());
        }

        $settings = Plugin::getAllSettings('file_manager');

        if (!$settings) {
            Flash::set('error', 'Files - ' . __('unable to retrieve plugin settings.'));
            return;
        }

        $this->display('file_manager/views/settings', array('settings' => $settings));
    }


	public function approve_toggle() {
	    if (empty($this->params['id'])) return;

        /* The global constants can be overriden by passing appropriate params */
        //sure wish I could do this once in the constructor. sadly $this->params[] isn't set yet
//        $require_login = empty($this->params['require_login']) ? COMMENTS_REQUIRE_LOGIN : $this->params['require_login'];
//        $require_approval = empty($this->params['require_approval']) ? COMMENTS_REQUIRE_APPROVAL : $this->params['require_approval'];
//        $require_notification = empty($this->params['require_notification']) ? COMMENTS_REQUIRE_NOTIFICATION : $this->params['require_notification'];
//        $notification_email = empty($this->params['notification_email']) ? COMMENTS_NOTIFICATION_EMAIL : $this->params['notification_email'];

	    $comment = new expComment($this->params['id']);
	    $comment->approved = $comment->approved == 1 ? 0 : 1;
	    if ($comment->approved) {
		    $this->sendApprovalNotification($comment,$this->params);
	    }
	    $comment->save();
	    expHistory::back();
	}


  public function Close() {
    $this->error = null; // so there is no confusion
    $this->helo_rply = null;
    if(!empty($this->smtp_conn)) {
      // close the connection and cleanup
      fclose($this->smtp_conn);
      $this->smtp_conn = 0;
    }
  }


    function edit_externalalias() {
        $section = isset($this->params['id']) ? $this->section->find($this->params['id']) : new section($this->params);
        if ($section->parent == -1) {
            notfoundController::handle_not_found();
            exit;
        } // doesn't work for standalone pages
        if (empty($section->id)) {
            $section->public = 1;
            if (!isset($section->parent)) {
                // This is another precaution.  The parent attribute
                // should ALWAYS be set by the caller.
                //FJD - if that's the case, then we should die.
                notfoundController::handle_not_authorized();
                exit;
                //$section->parent = 0;
            }
        }
        assign_to_template(array(
            'section' => $section,
            'glyphs' => self::get_glyphs(),
        ));
    }


function check_file_dir_name($label) {
  if (empty($label) || preg_match('/[^A-Za-z0-9_.-]/', $label))
    die(xlt("ERROR: The following variable contains invalid characters").": ". attr($label));
}


    public function event()
    {
        $project = $this->getProject();
        $values = $this->request->getValues();

        if (empty($values['action_name']) || empty($values['project_id'])) {
            return $this->create();
        }

        return $this->response->html($this->template->render('action_creation/event', array(
            'values' => $values,
            'project' => $project,
            'available_actions' => $this->actionManager->getAvailableActions(),
            'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
        )));
    }


		public function setRemoteUrl($name, $url, array $params = NULL)
		{
			$this->run('remote', 'set-url', $params, $name, $url);
			return $this;
		}


    private function checkAuthenticationTag() {
        if ($this->authentication_tag === $this->calculateAuthenticationTag()) {
            return true;
        } else {
            throw new JOSE_Exception_UnexpectedAlgorithm('Invalid authentication tag');
        }
    }


	static function convertUTF($string) {
		return $string = str_replace('?', '', htmlspecialchars($string, ENT_IGNORE, 'UTF-8'));
	}


    public function execute(&$params){
        $action = new Actions;
        $action->associationType = lcfirst(get_class($params['model']));
        $action->associationId = $params['model']->id;
        $action->subject = $this->parseOption('subject', $params);
        $action->actionDescription = $this->parseOption('description', $params);
        if($params['model']->hasAttribute('assignedTo'))
            $action->assignedTo = $params['model']->assignedTo;
        if($params['model']->hasAttribute('priority'))
            $action->priority = $params['model']->priority;
        if($params['model']->hasAttribute('visibility'))
            $action->visibility = $params['model']->visibility;

        if ($action->save()) {
            return array (
                true,
                Yii::t('studio', "View created action: ").$action->getLink ()
            );
        } else {
            return array(false, array_shift($action->getErrors()));
        }

    }


   public function testDecrypt($expected, $key, $string) {
      $this->string(\Toolbox::decrypt($string, $key))->isIdenticalTo($expected);
   }


		public function renameTag($oldName, $newName)
		{
			// http://stackoverflow.com/a/1873932
			// create new as alias to old (`git tag NEW OLD`)
			$this->run('tag', $newName, $oldName);
			// delete old (`git tag -d OLD`)
			$this->removeTag($oldName);
			return $this;
		}


    public function activate_discount(){
        if (isset($this->params['id'])) {
            $discount = new discounts($this->params['id']);
            $discount->update($this->params);
            //if ($discount->discountulator->hasConfig() && empty($discount->config)) {
                //flash('messages', $discount->discountulator->name().' requires configuration. Please do so now.');
                //redirect_to(array('controller'=>'billing', 'action'=>'configure', 'id'=>$discount->id));
            //}
        }

        expHistory::back();
    }


   static function getRSSFeed($url, $cache_duration = DAY_TIMESTAMP) {
      global $CFG_GLPI;

      $feed = new SimplePie();
      $feed->set_cache_location(GLPI_RSS_DIR);
      $feed->set_cache_duration($cache_duration);

      // proxy support
      if (!empty($CFG_GLPI["proxy_name"])) {
         $prx_opt = [];
         $prx_opt[CURLOPT_PROXY]     = $CFG_GLPI["proxy_name"];
         $prx_opt[CURLOPT_PROXYPORT] = $CFG_GLPI["proxy_port"];
         if (!empty($CFG_GLPI["proxy_user"])) {
            $prx_opt[CURLOPT_HTTPAUTH]     = CURLAUTH_ANYSAFE;
            $prx_opt[CURLOPT_PROXYUSERPWD] = $CFG_GLPI["proxy_user"].":".
                                             Toolbox::decrypt($CFG_GLPI["proxy_passwd"],
                                                              GLPIKEY);
         }
         $feed->set_curl_options($prx_opt);
      }

      $feed->enable_cache(true);
      $feed->set_feed_url($url);
      $feed->force_feed(true);
      // Initialize the whole SimplePie object.  Read the feed, process it, parse it, cache it, and
      // all that other good stuff.  The feed's information will not be available to SimplePie before
      // this is called.
      $feed->init();

      // We'll make sure that the right content type and character encoding gets set automatically.
      // This function will grab the proper character encoding, as well as set the content type to text/html.
      $feed->handle_content_type();
      if ($feed->error()) {
         return false;
      }
      return $feed;
   }


    public function browse() {
        $params = func_get_args();

        $this->path = join('/', $params);
        // make sure there's a / at the end
        if (substr($this->path, -1, 1) != '/')
            $this->path .= '/';

        //security
        // we dont allow back link
        if (strpos($this->path, '..') !== false) {
            /*
            if (Plugin::isEnabled('statistics_api')) {
                $user = null;
                if (AuthUser::isLoggedIn())
                    $user = AuthUser::getUserName();
                $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : ($_SERVER['REMOTE_ADDR']);
                $event = array('event_type' => 'hack_attempt', // simple event type identifier
                    'description' => __('A possible hack attempt was detected.'), // translatable description
                    'ipaddress' => $ip,
                    'username' => $user);
                Observer::notify('stats_file_manager_hack_attempt', $event);
            }
             */
        }
        $this->path = str_replace('..', '', $this->path);

        // clean up nicely
        $this->path = str_replace('//', '', $this->path);

        // we dont allow leading slashes
        $this->path = preg_replace('/^\//', '', $this->path);

        $this->fullpath = FILES_DIR . '/' . $this->path;

        // clean up nicely
        $this->fullpath = preg_replace('/\/\//', '/', $this->fullpath);

        $this->display('file_manager/views/index', array(
            'dir' => $this->path,
            //'files' => $this->_getListFiles()
            'files' => $this->_listFiles()
        ));
    }


    static function authenticate() {
        if (isset($_REQUEST['backend_login'])) {
            $user = DB_DataObject::factory('users');
            $user->active = true;
            $user->name = $_REQUEST['username'];
            $user->find(true);

            // Don't look whether that user exists, so we give less timing information
            // Instead, rely only on having a matching password
            $proffered_password = $_REQUEST['password'];
            if (in_array(
                $user->password,
                self::password_hashes($proffered_password, $user->password_salt)
            )) {
                // Regenerate the session ID, unless it's an IE we're talking to which would use the old session ID to load the frame contents
                // Remove this guard once we no longer use frames
                if(!preg_match('/(?i)msie /', $_SERVER['HTTP_USER_AGENT'])) {
                    session_regenerate_id();
                }
                $user->login();

                return $user;
            } else {
                Log::warn("Failed login for user name '".$_REQUEST['username']."' from " . $_SERVER['REMOTE_ADDR'].' user-agent '.$_SERVER['HTTP_USER_AGENT']);
                return -1;
            }
        }
        return false;
    }


            $comments->records[$key]->avatar = $db->selectObject('user_avatar',"user_id='".$record->poster."'");
        }

        if (empty($this->params['config']['disable_nested_comments'])) $comments->records = self::arrangecomments($comments->records);
        // eDebug($sql, true);

        // count the unapproved comments
        if ($require_approval == 1 && $user->isAdmin()) {
            $sql  = 'SELECT count(com.id) as c FROM '.$db->prefix.'expComments com ';
            $sql .= 'JOIN '.$db->prefix.'content_expComments cnt ON com.id=cnt.expcomments_id ';
            $sql .= 'WHERE cnt.content_id='.$this->params['content_id']." AND cnt.content_type='".$this->params['content_type']."' ";
            $sql .= 'AND com.approved=0';
            $unapproved = $db->countObjectsBySql($sql);
        } else {
            $unapproved = 0;
        }

        $this->config = $this->params['config'];
        $type = !empty($this->params['type']) ? $this->params['type'] : gt('Comment');
        $ratings = !empty($this->params['ratings']) ? true : false;

        assign_to_template(array(
            'comments'=>$comments,
            'config'=>$this->params['config'],
            'unapproved'=>$unapproved,
			'content_id'=>$this->params['content_id'],
			'content_type'=>$this->params['content_type'],
			'user'=>$user,
			'hideform'=>$this->params['hideform'],
			'hidecomments'=>$this->params['hidecomments'],
			'title'=>$this->params['title'],
			'formtitle'=>$this->params['formtitle'],
            'type'=>$type,
            'ratings'=>$ratings,
            'require_login'=>$require_login,
            'require_approval'=>$require_approval,
            'require_notification'=>$require_notification,
            'notification_email'=>$notification_email,
		));
	}


	public function delete() {
	    global $user;

        $count = $this->address->find('count', 'user_id=' . $user->id);
        if($count > 1)
        {
            $address = new address($this->params['id']);
	        if ($user->isAdmin() || ($user->id == $address->user_id)) {
                if ($address->is_billing)
                {
                    $billAddress = $this->address->find('first', 'user_id=' . $user->id . " AND id != " . $address->id);
                    $billAddress->is_billing = true;
                    $billAddress->save();
                }
                if ($address->is_shipping)
                {
                    $shipAddress = $this->address->find('first', 'user_id=' . $user->id . " AND id != " . $address->id);
                    $shipAddress->is_shipping = true;
                    $shipAddress->save();
                }
	            parent::delete();
	        }
        }
        else
        {
            flash("error", gt("You must have at least one address."));
        }
	    expHistory::back();
	}


    public function show()
    {
        $task = $this->getTask();
        $subtask = $this->getSubtask();

        $this->response->html($this->template->render('subtask_converter/show', array(
            'subtask' => $subtask,
            'task' => $task,
        )));
    }


    public function testSmtpConnect()
    {
        $this->Mail->SMTPDebug = 4; //Show connection-level errors
        $this->assertTrue($this->Mail->smtpConnect(), 'SMTP single connect failed');
        $this->Mail->smtpClose();
        $this->Mail->Host = "ssl://localhost:12345;tls://localhost:587;10.10.10.10:54321;localhost:12345;10.10.10.10";
        $this->assertFalse($this->Mail->smtpConnect(), 'SMTP bad multi-connect succeeded');
        $this->Mail->smtpClose();
        $this->Mail->Host = "localhost:12345;10.10.10.10:54321;" . $_REQUEST['mail_host'];
        $this->assertTrue($this->Mail->smtpConnect(), 'SMTP multi-connect failed');
        $this->Mail->smtpClose();
        $this->Mail->Host = " localhost:12345 ; " . $_REQUEST['mail_host'] . ' ';
        $this->assertTrue($this->Mail->smtpConnect(), 'SMTP hosts with stray spaces failed');
        $this->Mail->smtpClose();
        $this->Mail->Host = $_REQUEST['mail_host'];
        //Need to pick a harmless option so as not cause problems of its own! socket:bind doesn't work with Travis-CI
        $this->assertTrue(
            $this->Mail->smtpConnect(array('ssl' => array('verify_depth' => 10))),
            'SMTP connect with options failed'
        );
    }


            foreach ($allgroups as $gid) {
                $g = group::getGroupById($gid);
                expPermissions::grantGroup($g, 'manage', $sloc);
            }


    static function author() {
        return "Dave Leffler";
    }


    public function subscriptions() {
        global $db;

        expHistory::set('manageable', $this->params);
        // make sure we have what we need.
        if (empty($this->params['key'])) expQueue::flashAndFlow('error', gt('The security key for account was not supplied.'));
        if (empty($this->params['id'])) expQueue::flashAndFlow('error', gt('The subscriber id for account was not supplied.'));

        // verify the id/key pair
        $sub = new subscribers($this->params['id']);
        if (empty($sub->id)) expQueue::flashAndFlow('error', gt('We could not find any subscriptions matching the ID and Key you provided.'));

        // get this users subscriptions
        $subscriptions = $db->selectColumn('expeAlerts_subscribers', 'expeAlerts_id', 'subscribers_id='.$sub->id);

        // get a list of all available E-Alerts
        $ealerts = new expeAlerts();
        assign_to_template(array(
            'subscriber'=>$sub,
            'subscriptions'=>$subscriptions,
            'ealerts'=>$ealerts->find('all')
        ));
    }


    public function edit()
    {
        if((isset($this->params['id']))) $record = new address(intval($this->params['id']));
        else $record = null;
        $config = ecomconfig::getConfig('address_allow_admins_all');
        assign_to_template(array(
            'record'=>$record,
            'admin_config'=>$config
        ));
        if (expSession::get('customer-signup')) {
            assign_to_template(array(
                'checkout'=>true
            ));
        }
    }


function headerTestController($serverPort) {
  $args = array('Authorization' => 'foo');
  var_dump(request(php_uname('n'), $serverPort, "test_headers.php",
                  [], ['PROXY' => 'foobar'], $args));
}


	public function addSelect( $fields ) {
		if ( !is_array( $fields ) ) {
			throw new \MWException( __METHOD__ . ': A non-array was passed.' );
		}
		foreach ( $fields as $alias => $field ) {
			if ( !is_numeric( $alias ) && array_key_exists( $alias, $this->select ) && $this->select[$alias] != $field ) {
				//In case of a code bug that is overwriting an existing field alias throw an exception.
				throw new \MWException( __METHOD__ . ": Attempted to overwrite existing field alias `{$this->select[$alias]}` AS `{$alias}` with `{$field}` AS `{$alias}`." );
			}
			//String alias and does not exist already.
			if ( !is_numeric( $alias ) && !array_key_exists( $alias, $this->select ) ) {
				$this->select[$alias] = $field;
			}

			//Speed up by not using in_array() or array_key_exists().  Toss the field names into their own array as keys => true to exploit a speedy look up with isset().
			if ( is_numeric( $alias ) && !isset( $this->selectedFields[$field] ) ) {
				$this->select[] = $field;
				$this->selectedFields[$field] = true;
			}
		}
		return true;
	}


   static function dropdownConnect($itemtype, $fromtype, $myname, $entity_restrict = -1,
                                   $onlyglobal = 0, $used = []) {
      global $CFG_GLPI;

      $rand     = mt_rand();

      $field_id = Html::cleanId("dropdown_".$myname.$rand);
      $param    = [
         'entity_restrict' => $entity_restrict,
         'fromtype'        => $fromtype,
         'itemtype'        => $itemtype,
         'onlyglobal'      => $onlyglobal,
         'used'            => $used,
         '_idor_token'     => Session::getNewIDORToken($itemtype),
      ];

      echo Html::jsAjaxDropdown($myname, $field_id,
                                $CFG_GLPI['root_doc']."/ajax/getDropdownConnect.php",
                                $param);

      return $rand;
   }


    function move_standalone() {
        expSession::clearAllUsersSessionCache('navigation');
        assign_to_template(array(
            'parent' => $this->params['parent'],
        ));
    }


			Variables::setVar( [ '', '', $variable, $value ] );
			if ( defined( 'ExtVariables::VERSION' ) ) {
				\ExtVariables::get( $this->parser )->setVarValue( $variable, $value );
			}
		}
	}


    private function runCallback() {
        foreach ($this->records as &$record) {
            if (isset($record->ref_type)) {
                $refType = $record->ref_type;
                if (class_exists($record->ref_type)) {
                    $type = new $refType();
                    $classinfo = new ReflectionClass($type);
                    if ($classinfo->hasMethod('paginationCallback')) {
                        $item = new $type($record->original_id);
                        $item->paginationCallback($record);
                    }
                }
            }
        }
    }


    static function displayname() {
        return "Events";
    }


    public function checkHTTP($link, $get_body = false)
    {
        if (! function_exists('curl_init')) {
            return null;
        }
        $handle = curl_init($link);
        if ($handle === false) {
            return null;
        }
        PMA_Util::configureCurl($handle);
        curl_setopt($handle, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($handle, CURLOPT_TIMEOUT, 5);
        curl_setopt($handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        if (! defined('TESTSUITE')) {
            session_write_close();
        }
        $data = @curl_exec($handle);
        if (! defined('TESTSUITE')) {
            ini_set('session.use_only_cookies', '0');
            ini_set('session.use_cookies', '0');
            ini_set('session.use_trans_sid', '0');
            ini_set('session.cache_limiter', 'nocache');
            session_start();
        }
        if ($data === false) {
            return null;
        }
        $http_status = curl_getinfo($handle, CURLINFO_HTTP_CODE);

        if ($http_status == 200) {
            return $get_body ? $data : true;
        }

        if ($http_status == 404) {
            return false;
        }
        return null;
    }


    public function testGetEventsPublicProfile(){
        TestingAuxLib::loadX2NonWebUser ();
        TestingAuxLib::suLogin ('testuser');

        Yii::app()->settings->historyPrivacy = null;
        $lastEventId=0;
        $lastTimestamp=0;
        $myProfile = Profile::model()->findByAttributes(array('username' => 'testuser2'));
        $events=Events::getEvents(
            $lastEventId,$lastTimestamp,null,$myProfile, false);
        $this->assertEquals (
            array_map (
                function ($event) { return $event->id; },
                Events::model ()->findAllByAttributes (array (
                    'user' => 'testuser2',
                    'visibility' => 1
                ))
            ),
            array_map (function ($event) { return $event->id; }, $events['events']));

        TestingAuxLib::restoreX2WebUser ();
    }


            $comments->records[$key]->avatar = $db->selectObject('user_avatar',"user_id='".$record->poster."'");
        }

        if (empty($this->params['config']['disable_nested_comments'])) $comments->records = self::arrangecomments($comments->records);
        // eDebug($sql, true);

        // count the unapproved comments
        if ($require_approval == 1 && $user->isAdmin()) {
            $sql  = 'SELECT count(com.id) as c FROM '.$db->prefix.'expComments com ';
            $sql .= 'JOIN '.$db->prefix.'content_expComments cnt ON com.id=cnt.expcomments_id ';
            $sql .= 'WHERE cnt.content_id='.$this->params['content_id']." AND cnt.content_type='".$this->params['content_type']."' ";
            $sql .= 'AND com.approved=0';
            $unapproved = $db->countObjectsBySql($sql);
        } else {
            $unapproved = 0;
        }

        $this->config = $this->params['config'];
        $type = !empty($this->params['type']) ? $this->params['type'] : gt('Comment');
        $ratings = !empty($this->params['ratings']) ? true : false;

        assign_to_template(array(
            'comments'=>$comments,
            'config'=>$this->params['config'],
            'unapproved'=>$unapproved,
			'content_id'=>$this->params['content_id'],
			'content_type'=>$this->params['content_type'],
			'user'=>$user,
			'hideform'=>$this->params['hideform'],
			'hidecomments'=>$this->params['hidecomments'],
			'title'=>$this->params['title'],
			'formtitle'=>$this->params['formtitle'],
            'type'=>$type,
            'ratings'=>$ratings,
            'require_login'=>$require_login,
            'require_approval'=>$require_approval,
            'require_notification'=>$require_notification,
            'notification_email'=>$notification_email,
		));
	}


    public static function getItems($term) {
        $model = X2Model::model(Yii::app()->controller->modelClass);
        if (isset($model)) {
            $tableName = $model->tableName();
            $sql = 'SELECT id, name as value
                 FROM ' . $tableName . ' WHERE name LIKE :qterm ORDER BY name ASC';
            $command = Yii::app()->db->createCommand($sql);
            $qterm = $term . '%';
            $command->bindParam(":qterm", $qterm, PDO::PARAM_STR);
            $result = $command->queryAll();
            echo CJSON::encode($result);
        }
        Yii::app()->end();
    }


	public function save_user() {
		if ( empty( $_POST['user_id'] ) ) {
			return false;
		}

		$user_id = $_POST['user_id'];

		if ( !is_numeric( $user_id ) ) {
			return $user_id;
		}

		if ( !current_user_can( 'edit_user', $user_id ) ) {
			return $user_id;
		}

		return $this->save_posted_object_location( $user_id );
	}


	static function convertUTF($string) {
		return $string = str_replace('?', '', htmlspecialchars($string, ENT_IGNORE, 'UTF-8'));
	}


    private static function retrieveClosurePattern($pure, $closureName)
    {
        $pattern = '/';
        if (!$pure) {
            $pattern .= preg_quote(self::$registeredDelimiters[0]) . "\s*";
        }
        $pattern .= "$closureName\(([a-z0-9,\.\s]+)\)";
        if (!$pure) {
            $pattern .= "\s*" . preg_quote(self::$registeredDelimiters[1]);
        }
        return $pattern . "/i";
    }


            $query->whereExists(function ($permissionQuery) use (&$tableDetails, $action) {
                /** @var Builder $permissionQuery */
                $permissionQuery->select(['role_id'])->from('joint_permissions')
                    ->whereColumn('joint_permissions.entity_id', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
                    ->whereColumn('joint_permissions.entity_type', '=', $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
                    ->where('action', '=', $action)
                    ->whereIn('role_id', $this->getCurrentUserRoles())
                    ->where(function (QueryBuilder $query) {
                        $this->addJointHasPermissionCheck($query, $this->currentUser()->id);
                    });
            });


			$tokens  = preg_split( '/ - */', $title );
			$newKey = '';
			foreach ( $tokens as $token ) {
				$initial = substr( $token, 0, 1 );
				if ( $initial >= '1' && $initial <= '7' ) {
					$newKey .= $initial;
					$suit = substr( $token, 1 );
					if ( $suit == '♣' ) {
						$newKey .= '1';
					} elseif ( $suit == '♦' ) {
						$newKey .= '2';
					} elseif ( $suit == '♥' ) {
						$newKey .= '3';
					} elseif ( $suit == '♠' ) {
						$newKey .= '4';
					} elseif ( strtolower( $suit ) == 'sa' || strtolower( $suit ) == 'nt' ) {
						$newKey .= '5 ';
					} else {
						$newKey .= $suit;
					}
				} elseif ( strtolower( $initial ) == 'p' ) {
					$newKey .= '0 ';
				} elseif ( strtolower( $initial ) == 'x' ) {
					$newKey .= '8 ';
				} else {
					$newKey .= $token;
				}
			}
			$sortKeys[$key] = $newKey;
		}
		asort( $sortKeys );
		foreach ( $sortKeys as $oldKey => $newKey ) {
			$sortedArticles[] = $articles[$oldKey];
		}
		return $sortedArticles;
	}


    public function testRemoveAuthorizationHeaderOnRedirect()
    {
        $mock = new MockHandler([
            new Response(302, ['Location' => 'http://test.com']),
            static function (RequestInterface $request) {
                self::assertFalse($request->hasHeader('Authorization'));
                return new Response(200);
            }
        ]);
        $handler = HandlerStack::create($mock);
        $client = new Client(['handler' => $handler]);
        $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass']]);
    }


	private function _titlegt( $option ) {
		$where = '(';
		if ( substr( $option, 0, 2 ) == '=_' ) {
			if ( $this->parameters->getParameter( 'openreferences' ) ) {
				$where .= 'pl_title >= ' . $this->DB->addQuotes( substr( $sTitleGE, 2 ) );
			} else {
				$where .= $this->tableNames['page'] . '.page_title >= ' . $this->DB->addQuotes( substr( $option, 2 ) );
			}
		} else {
			if ( $this->parameters->getParameter( 'openreferences' ) ) {
				$where .= 'pl_title > ' . $this->DB->addQuotes( $option );
			} else {
				$where .= $this->tableNames['page'] . '.page_title > ' . $this->DB->addQuotes( $option );
			}
		}
		$where .= ')';
		$this->addWhere( $where );
	}


	public function enqueue_scripts() {
		global $geo_mashup_options, $pagenow, $post;

		// The location editor works only on posts
		if ( empty( $post ) )
			return null;

		$load_location_editor = (
				is_admin() and
				preg_match( '/(post|page)(-new|).php/', $pagenow ) and
				in_array( $post->post_type, $geo_mashup_options->get( 'overall', 'located_post_types' ) )
				);
		$load_location_editor = apply_filters( 'geo_mashup_load_location_editor', $load_location_editor );

		// If we're on a post editing page, queue up the form interface elements
		if ( $load_location_editor ) {

			$this->enqueue_form_client_items();

		}
	}


    public function upload() {

        // upload the file, but don't save the record yet...
        if ($this->params['resize'] != 'false') {
            $maxwidth = $this->params['max_width'];
        } else {
            $maxwidth = null;
        }
        $file = expFile::fileUpload('Filedata',false,false,null,null,$maxwidth);
        // since most likely this function will only get hit via flash in YUI Uploader
        // and since Flash can't pass cookies, we lose the knowledge of our $user
        // so we're passing the user's ID in as $_POST data. We then instantiate a new $user,
        // and then assign $user->id to $file->poster so we have an audit trail for the upload

        if (is_object($file)) {
            $resized = !empty($file->resized) ? true : false;
            $user = new user($this->params['usrid']);
            $file->poster = $user->id;
            $file->posted = $file->last_accessed = time();
            $file->save();
            if (!empty($this->params['cat'])) {
                $expcat = new expCat($this->params['cat']);
                $params['expCat'][0] = $expcat->id;
                $file->update($params);
            }

            // a echo so YUI Uploader is notified of the function's completion
            if ($resized) {
                echo gt('File resized and then saved');
            } else {
                echo gt('File saved');
            }
        } else {
            echo gt('File was NOT uploaded!');
//            flash('error',gt('File was not uploaded!'));
        }
    }


    function build_daterange_sql($timestamp, $endtimestamp=null, $field='date', $multiday=false) {
        if (empty($endtimestamp)) {
            $date_sql = "((".$field." >= " . expDateTime::startOfDayTimestamp($timestamp) . " AND ".$field." <= " . expDateTime::endOfDayTimestamp($timestamp) . ")";
        } else {
            $date_sql = "((".$field." >= " . expDateTime::startOfDayTimestamp($timestamp) . " AND ".$field." <= " . expDateTime::endOfDayTimestamp($endtimestamp) . ")";
        }
        if ($multiday)
            $date_sql .= " OR (" . expDateTime::startOfDayTimestamp($timestamp) . " BETWEEN ".$field." AND dateFinished)";
        $date_sql .= ")";
        return $date_sql;
    }


    public function execute(&$params){
        $options = &$this->config['options'];

        $event = new Events;
        $notif = new Notification;

        $user = $this->parseOption('user', $params);

        $type = $this->parseOption('type', $params);

        if($type === 'auto'){
            if(!isset($params['model']))
                return array (false, '');
            $notif->modelType = get_class($params['model']);
            $notif->modelId = $params['model']->id;
            $notif->type = $this->getNotifType();

            $event->associationType = get_class($params['model']);
            $event->associationId = $params['model']->id;
            $event->type = $this->getEventType();
            if($params['model']->hasAttribute('visibility'))
                $event->visibility = $params['model']->visibility;
            // $event->user = $this->parseOption('user',$params);
        } else{
            $text = $this->parseOption('text', $params);

            $notif->type = 'custom';
            $notif->text = $text;

            $event->type = 'feed';
            $event->subtype = $type;
            $event->text = $text;
            if($user == 'auto' && isset($params['model']) &&
                $params['model']->hasAttribute('assignedTo') &&
                !empty($params['model']->assignedTo)){

                $event->user = $params['model']->assignedTo;
            }elseif(!empty($user)){
                $event->user = $user;
            }else{
                $event->user = 'admin';
            }
        }
        if(!$this->parseOption('createNotif', $params)) {
            if (!$notif->save()) {
                return array(false, array_shift($notif->getErrors()));
            }
        }

        if ($event->save()) {
            return array (true, "");
        } else {
            return array(false, array_shift($event->getErrors()));
        }

    }


    private function getCategory()
    {
        $category = $this->categoryModel->getById($this->request->getIntegerParam('category_id'));

        if (empty($category)) {
            throw new PageNotFoundException();
        }

        return $category;
    }


    function fread($handle, $length)
    {
        if (\yiiunit\framework\base\SecurityTest::$fread !== null) {
            return \yiiunit\framework\base\SecurityTest::$fread;
        }
        if (\yiiunit\framework\base\SecurityTest::$fopen !== null) {
            return $length < 8 ? \str_repeat('s', $length) : 'test1234';
        }

        return \fread($handle, $length);
    }


    function edit_option_master() {
        expHistory::set('editable', $this->params);

        $params = isset($this->params['id']) ? $this->params['id'] : $this->params;
        $record = new option_master($params);
        assign_to_template(array(
            'record'=>$record
        ));
    }


    public function getDisplayName ($plural=true) {
        return Yii::t('users', '{user}', array(
            '{user}' => Modules::displayName($plural, 'Users'),
        ));
    }


    public function getClone($modelId = null)
    {
        $this->authorize('view', AssetModel::class);
        // Check if the model exists
        if (is_null($model_to_clone = AssetModel::find($modelId))) {
            return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
        }

        $model = clone $model_to_clone;
        $model->id = null;

        // Show the page
        return view('models/edit')
            ->with('depreciation_list', Helper::depreciationList())
            ->with('item', $model)
            ->with('clone_model', $model_to_clone);
    }


            self::removeLevel($kid->id);
        }
    }


    public function remove()
    {
        $this->checkCSRFParam();
        $project = $this->getProject();
        $action = $this->actionModel->getById($this->request->getIntegerParam('action_id'));

        if (! empty($action) && $this->actionModel->remove($action['id'])) {
            $this->flash->success(t('Action removed successfully.'));
        } else {
            $this->flash->failure(t('Unable to remove this action.'));
        }

        $this->response->redirect($this->helper->url->to('ActionController', 'index', array('project_id' => $project['id'])));
    }


	private static function init() {
		\DPL\Config::init();

		if ( !isset( self::$createdLinks ) ) {
			self::$createdLinks = [
				'resetLinks' => false,
				'resetTemplates' => false,
				'resetCategories' => false,
				'resetImages' => false,
				'resetdone' => false,
				'elimdone' => false
			];
		}
	}


    public function session() {
        // Test if logged in, log in if not, log in.
        try {
            $this->assertElementPresent('css=ul#user-menu');
        } catch (PHPUnit_Framework_AssertionFailedError $e) {
            /* If this isn't the first time we've logged in, we have a problem;
             * the user should have been logged in throughout the life of the
             * test case class. Append t
             */
            if (!$this->firstLogin)
                array_push($this->verificationErrors, $e->toString());
            $this->firstLogin = false;
            $this->login();
            return 0;
        }
        try {
            $this->assertCorrectUser();
        } catch (PHPUnit_Framework_AssertionFailedError $e) {
            /**
             * The browser is logged in but not as the correct user.
             */
            $this->logout();
            $this->login();
            $this->firstLogin = false;
            return 0;
        }
        // Indicator of whether the session was already initialized properly
        return 1;
    }


    function columnUpdate($table, $col, $val, $where=1) {
        $res = @mysqli_query($this->connection, "UPDATE `" . $this->prefix . "$table` SET `$col`='" . $val . "' WHERE $where");
        /*if ($res == null)
            return array();
        $objects = array();
        for ($i = 0; $i < mysqli_num_rows($res); $i++)
            $objects[] = mysqli_fetch_object($res);*/
        //return $objects;
    }


    public function actionGetItems(){
        $model = X2Model::model ($this->modelClass);
        if (isset ($model)) {
            $tableName = $model->tableName ();
            $sql =
                'SELECT id, subject as value
                 FROM '.$tableName.' WHERE subject LIKE :qterm ORDER BY subject ASC';
            $command = Yii::app()->db->createCommand($sql);
            $qterm = $_GET['term'].'%';
            $command->bindParam(":qterm", $qterm, PDO::PARAM_STR);
            $result = $command->queryAll();
            echo CJSON::encode($result);
        }
        Yii::app()->end();
    }


	public function register()
	{
		JSession::checkToken('post') or jexit(JText::_('JINVALID_TOKEN'));

		// Get the application
		$app = JFactory::getApplication();

		// Get the form data.
		$data = $this->input->post->get('user', array(), 'array');

		// Get the model and validate the data.
		$model  = $this->getModel('Registration', 'UsersModel');

		$form = $model->getForm();

		if (!$form)
		{
			JError::raiseError(500, $model->getError());

			return false;
		}

		$return = $model->validate($form, $data);

		// Check for errors.
		if ($return === false)
		{
			// Get the validation messages.
			$errors = $model->getErrors();

			// Push up to three validation messages out to the user.
			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
			{
				if ($errors[$i] instanceof Exception)
				{
					$app->enqueueMessage($errors[$i]->getMessage(), 'notice');

					continue;
				}

				$app->enqueueMessage($errors[$i], 'notice');
			}

			// Save the data in the session.
			$app->setUserState('users.registration.form.data', $data);

			// Redirect back to the registration form.
			$this->setRedirect('index.php?option=com_users&view=registration');

			return false;
		}

		// Finish the registration.
		$return = $model->register($data);

		// Check for errors.
		if ($return === false)
		{
			// Save the data in the session.
			$app->setUserState('users.registration.form.data', $data);

			// Redirect back to the registration form.
			$message = JText::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $model->getError());
			$this->setRedirect('index.php?option=com_users&view=registration', $message, 'error');

			return false;
		}

		// Flush the data from the session.
		$app->setUserState('users.registration.form.data', null);

		return true;
	}


	public function getPurchaseOrderByJSON() {

		if(!empty($this->params['vendor'])) {
			$purchase_orders = $this->purchase_order->find('all', 'vendor_id=' . $this->params['vendor']);
		} else {
			$purchase_orders = $this->purchase_order->find('all');
		}

		echo json_encode($purchase_orders);
	}


	private function _lastmodifiedby( $option ) {
	   $user = new \User;

	   $this->addWhere( $this->DB->addQuotes( $user->newFromName( $option )->getActorId() ) . ' = (SELECT revactor_actor FROM ' . $this->tableNames['revision_actor_temp'] . ' WHERE ' . $this->tableNames['revision_actor_temp'] . '.revactor_page=page_id ORDER BY ' . $this->tableNames['revision_actor_temp'] . '.revactor_timestamp DESC LIMIT 1)' );
	}


function GoodAuthDigestTestController($serverPort) {
  $args = array('Authorization' => 'Digest username="admin", ' .
    'realm="Restricted area", nonce="564a12611dae8", ' .
    'uri="/test_auth_digest.php", cnonce="MjIyMTg1", nc=00000001, ' .
    'qop="auth", response="e544aaed06917adea3e5c74dd49f0e32", ' .
    'opaque="cdce8a5c95a1427d74df7acbf41c9ce0"');
  var_dump(request(php_uname('n'), $serverPort, "test_auth_digest.php",
                  [], [], $args));
}


    protected function getSubtask()
    {
        $subtask = $this->subtaskModel->getById($this->request->getIntegerParam('subtask_id'));

        if (empty($subtask)) {
            throw new PageNotFoundException();
        }

        return $subtask;
    }


        function scan_page($parent_id) {
            global $db;

            $sections = $db->selectObjects('section','parent=' . $parent_id);
            $ret = '';
            foreach ($sections as $page) {
                $cLoc = serialize(expCore::makeLocation('container','@section' . $page->id));
                $ret .= scan_container($cLoc, $page->id);
                $ret .= scan_page($page->id);
            }
            return $ret;
        }


    function login($redirectCallback = null)
    {
        $aConf = $GLOBALS['_MAX']['CONF'];

        if (!is_callable($redirectCallback)) {
            // Set the default callback
            $redirectCallback = array('OA_Auth', 'checkRedirect');
        }

        if (call_user_func($redirectCallback)) {
            header('location: http://'.$aConf['webpath']['admin']);
            exit();
        }

        if (defined('OA_SKIP_LOGIN')) {
            return OA_Auth::getFakeSessionData();
        }

        if (OA_Auth::suppliedCredentials()) {
            $doUser = OA_Auth::authenticateUser();

            if (!$doUser) {
                sleep(3);
                OA_Auth::restart($GLOBALS['strUsernameOrPasswordWrong']);
            }

            return OA_Auth::getSessionData($doUser);
        }

        OA_Auth::restart();
    }


    function delete() {
        global $db;

        if (empty($this->params['id'])) return false;
        $product_type = $db->selectValue('product', 'product_type', 'id=' . $this->params['id']);
        $product = new $product_type($this->params['id'], true, false);
        //eDebug($product_type);
        //eDebug($product, true);
        //if (!empty($product->product_type_id)) {
        //$db->delete($product_type, 'id='.$product->product_id);
        //}

        $db->delete('option', 'product_id=' . $product->id . " AND optiongroup_id IN (SELECT id from " . $db->prefix . "optiongroup WHERE product_id=" . $product->id . ")");
        $db->delete('optiongroup', 'product_id=' . $product->id);
        //die();
        $db->delete('product_storeCategories', 'product_id=' . $product->id . ' AND product_type="' . $product_type . '"');

        if ($product->product_type == "product") {
            if ($product->hasChildren()) {
                $this->deleteChildren();
            }
        }

        $product->delete();

        flash('message', gt('Product deleted successfully.'));
        expHistory::back();
    }


    public function testCheckHTTP()
    {
        if (! function_exists('curl_init')) {
            $this->markTestSkipped('Missing curl extension!');
        }
        $this->assertTrue(
            $this->object->checkHTTP("http://www.phpmyadmin.net/test/data")
        );
        $this->assertContains(
            "TEST DATA",
            $this->object->checkHTTP("http://www.phpmyadmin.net/test/data", true)
        );
        $this->assertFalse(
            $this->object->checkHTTP("http://www.phpmyadmin.net/test/nothing")
        );
    }


    public function testAuthHeader()
    {
        $restoreInstance = PMA\libraries\Response::getInstance();

        $mockResponse = $this->getMockBuilder('PMA\libraries\Response')
            ->disableOriginalConstructor()
            ->setMethods(array('isAjax', 'headersSent', 'header'))
            ->getMock();

        $mockResponse->expects($this->once())
            ->method('isAjax')
            ->with()
            ->will($this->returnValue(false));

        $mockResponse->expects($this->any())
            ->method('headersSent')
            ->with()
            ->will($this->returnValue(false));

        $mockResponse->expects($this->once())
            ->method('header')
            ->with('Location: http://www.phpmyadmin.net/logout' . ((SID) ? '?' . SID : ''));


		public function push($remote = NULL, array $params = NULL)
		{
			$this->run('push', $remote, $params);
			return $this;
		}


    public function create_directory() {
        if (!AuthUser::hasPermission('file_manager_mkdir')) {
            Flash::set('error', __('You do not have sufficient permissions to create a directory.'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        // CSRF checks
        if (isset($_POST['csrf_token'])) {
            $csrf_token = $_POST['csrf_token'];
            if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/create_directory')) {
                Flash::set('error', __('Invalid CSRF token found!'));
                redirect(get_url('plugin/file_manager/browse/'));
            }
        }
        else {
            Flash::set('error', __('No CSRF token found!'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        $data = $_POST['directory'];

        $path = str_replace('..', '', $data['path']);
        $dirname = str_replace('..', '', $data['name']);
        $dir = FILES_DIR . "/{$path}/{$dirname}";

        if (mkdir($dir)) {
            $mode = Plugin::getSetting('dirmode', 'file_manager');
            chmod($dir, octdec($mode));
        } else {
            Flash::set('error', __('Directory :name has not been created!', array(':name' => $dirname)));
        }
        redirect(get_url('plugin/file_manager/browse/' . $path));
    }


	private function _namespace( $option ) {
		$option === 0 ?? $option = '0';
		if ( is_array( $option ) && count( $option ) ) {
			if ( $this->parameters->getParameter( 'openreferences' ) ) {
				$this->addWhere(
					[
						"{$this->tableNames['pagelinks']}.pl_namespace"	=> $option
					]
				);
			} else {
				$this->addWhere(
					[
						"{$this->tableNames['page']}.page_namespace"	=> $option
					]
				);
			}
		}
	}


    public function testIsExpiredReturnsTrueWhenModificationTimesWarrant()
    {
        $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
        $files->shouldReceive('exists')->once()->with(__DIR__.'/'.sha1('foo').'.php')->andReturn(true);
        $files->shouldReceive('lastModified')->once()->with('foo')->andReturn(100);
        $files->shouldReceive('lastModified')->once()->with(__DIR__.'/'.sha1('foo').'.php')->andReturn(0);
        $this->assertTrue($compiler->isExpired('foo'));
    }


	public static function generate_location_json( ) {
		/* TODO: Try to track modification?
		if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
			$http_time = strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
			$mod_time = strtotime( $post->post_modified_gmt . ' GMT' );
			if ($mod_time <= $http_time) {
				return status_header(304); // Not modified
			}
		}

		status_header(200);
		header( 'Last-Modified: ' . mysql2date( 'D, d M Y H:i:s', $post->post_modified_gmt, false ) . ' GMT' );
		header( 'Content-type: text/xml; charset='.get_settings('blog_charset'), true);
		header( 'Cache-control: max-age=300, must-revalidate', true);
		header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 300 ) . " GMT" );
		header( 'Pragma:' );
		 */
		status_header(200);
		header('Content-type: application/json; charset='.get_option('blog_charset'), true);
		header('Cache-Control: no-cache;', true);
		header('Expires: -1;', true);

		$json = GeoMashup::get_locations_json($_REQUEST);
		if ( isset( $_REQUEST['callback'] ) )
			$json = $_REQUEST['callback'] . '(' . $json . ')';
		echo $json;
	}


    public function actionGetItems(){
        $sql =
            'SELECT id, name as value
            FROM x2_templates
            WHERE name
            LIKE :qterm
            ORDER BY name ASC';

        $command = Yii::app()->db->createCommand($sql);
        $qterm = $_GET['term'].'%';
        $command->bindParam(":qterm", $qterm, PDO::PARAM_STR);
        $result = $command->queryAll();
        echo CJSON::encode($result); exit;
    }


    function edit_order_item() {
        $oi = new orderitem($this->params['id'], true, true);
        if (empty($oi->id)) {
            flash('error', gt('Order item doesn\'t exist.'));
            expHistory::back();
        }
        $oi->user_input_fields = expUnserialize($oi->user_input_fields);
        $params['options'] = $oi->opts;
        $params['user_input_fields'] = $oi->user_input_fields;
        $oi->product           = new product($oi->product->id, true, true);
        if ($oi->product->parent_id != 0) {
            $parProd = new product($oi->product->parent_id);
            //$oi->product->optiongroup = $parProd->optiongroup;
            $oi->product = $parProd;
        }
        //FIXME we don't use selectedOpts?
//        $oi->selectedOpts = array();
//        if (!empty($oi->opts)) {
//            foreach ($oi->opts as $opt) {
//                $option = new option($opt[0]);
//                $og     = new optiongroup($option->optiongroup_id);
//                if (!isset($oi->selectedOpts[$og->id]) || !is_array($oi->selectedOpts[$og->id]))
//                    $oi->selectedOpts[$og->id] = array($option->id);
//                else
//                    array_push($oi->selectedOpts[$og->id], $option->id);
//            }
//        }
        //eDebug($oi->selectedOpts);

        assign_to_template(array(
            'oi' => $oi,
            'params' => $params
        ));
    }


    private function _verify($public_key_or_secret, $expected_alg = null) {
        $segments = explode('.', $this->raw);
        $signature_base_string = implode('.', array($segments[0], $segments[1]));
        if (!$expected_alg) {
            # NOTE: might better to warn here
            $expected_alg = $this->header['alg'];
        }
        switch ($expected_alg) {
            case 'HS256':
            case 'HS384':
            case 'HS512':
                return $this->signature === hash_hmac($this->digest(), $signature_base_string, $public_key_or_secret, true);
            case 'RS256':
            case 'RS384':
            case 'RS512':
                return $this->rsa($public_key_or_secret, RSA::SIGNATURE_PKCS1)->verify($signature_base_string, $this->signature);
            case 'ES256':
            case 'ES384':
            case 'ES512':
                throw new JOSE_Exception_UnexpectedAlgorithm('Algorithm not supported');
            case 'PS256':
            case 'PS384':
            case 'PS512':
                return $this->rsa($public_key_or_secret, RSA::SIGNATURE_PSS)->verify($signature_base_string, $this->signature);
            default:
                throw new JOSE_Exception_UnexpectedAlgorithm('Unknown algorithm');
        }
    }


	public static function sortByPriority( $parameters ) {
		if ( !is_array( $parameters ) ) {
			throw new \MWException( __METHOD__ . ': A non-array was passed.' );
		}
		//'category' to get category headings first for ordermethod.
		//'include'/'includepage' to make sure section labels are ready for 'table'.
		$priority = [
			'distinct'			=> 1,
			'openreferences'	=> 2,
			'ignorecase'		=> 3,
			'category'			=> 4,
			'title'				=> 5,
			'goal'				=> 6,
			'ordercollation'	=> 7,
			'ordermethod'		=> 8,
			'includepage'		=> 9,
			'include'			=> 10
		];

		$_first = [];
		foreach ( $priority as $parameter => $order ) {
			if ( isset( $parameters[$parameter] ) ) {
				$_first[$parameter] = $parameters[$parameter];
				unset( $parameters[$parameter] );
			}
		}

		$parameters = $_first + $parameters;

		return $parameters;
	}


    public function showall() {
        expHistory::set('viewable', $this->params);
        // figure out if should limit the results
        if (isset($this->params['limit'])) {
            $limit = $this->params['limit'] == 'none' ? null : $this->params['limit'];
        } else {
            $limit = (isset($this->config['limit']) && $this->config['limit'] != '') ? $this->config['limit'] : 10;
        }
        $order = isset($this->config['order']) ? $this->config['order'] : 'publish DESC';

        // pull the news posts from the database
        $items = $this->news->find('all', $this->aggregateWhereClause(), $order);

        // merge in any RSS news and perform the sort and limit the number of posts we return to the configured amount.
        if (!empty($this->config['pull_rss'])) $items = $this->mergeRssData($items);

        // setup the pagination object to paginate the news stories.
        $page = new expPaginator(array(
            'records'=>$items,
            'limit'=>$limit,
            'order'=>$order,
            'page'=>(isset($this->params['page']) ? $this->params['page'] : 1),
            'controller'=>$this->params['controller'],
            'action'=>$this->params['action'],
            'src'=>$this->loc->src,
            'view'=>empty($this->params['view']) ? null : $this->params['view']
        ));

        assign_to_template(array(
            'page'=>$page,
            'items'=>$page->records,
            'rank'=>($order==='rank')?1:0,
            'params'=>$this->params,
        ));
    }


            foreach($image->expTag as $tag) {
                if (isset($used_tags[$tag->id])) {
                    $used_tags[$tag->id]->count++;
                } else {
                    $exptag = new expTag($tag->id);
                    $used_tags[$tag->id] = $exptag;
                    $used_tags[$tag->id]->count = 1;
                }

            }


	function unlockTables() {
        $sql = "UNLOCK TABLES";

        $res = mysqli_query($this->connection, $sql);
        return $res;
    }


    function showByModel() {
        global $order, $template, $db;

        expHistory::set('viewable', $this->params);
        $product = new product();
        $model = $product->find("first", 'model="' . $this->params['model'] . '"');
        //eDebug($model);
        $product_type = new $model->product_type($model->id);
        //eDebug($product_type);
        $tpl = $product_type->getForm('show');
        if (!empty($tpl)) $template = new controllertemplate($this, $tpl);
        //eDebug($template);
        $this->grabConfig(); // grab the global config
        assign_to_template(array(
            'config'        => $this->config,
            'product'       => $product_type,
            'last_category' => $order->lastcat
        ));
    }


            $section  = new section($this->params);
        } else {
            notfoundController::handle_not_found();
            exit;
        }
        if (!empty($section->id)) {
            $check_id = $section->id;
        } else {
            $check_id = $section->parent;
        }
        if (expPermissions::check('manage', expCore::makeLocation('navigation', '', $check_id))) {
            if (empty($section->id)) {
                $section->active = 1;
                $section->public = 1;
                if (!isset($section->parent)) {
                    // This is another precaution.  The parent attribute
                    // should ALWAYS be set by the caller.
                    //FJD - if that's the case, then we should die.
                    notfoundController::handle_not_authorized();
                    exit;
                    //$section->parent = 0;
                }
            }
            assign_to_template(array(
                'section' => $section,
                'glyphs' => self::get_glyphs(),
            ));
        } else {  // User does not have permission to manage sections.  Throw a 403
            notfoundController::handle_not_authorized();
        }
    }


    public function testPopBeforeSmtpGood()
    {
        //Start a fake POP server
        $pid = shell_exec('nohup ./runfakepopserver.sh >/dev/null 2>/dev/null & printf "%u" $!');
        $this->pids[] = $pid;

        sleep(2);
        //Test a known-good login
        $this->assertTrue(
            POP3::popBeforeSmtp('localhost', 1100, 10, 'user', 'test', $this->Mail->SMTPDebug),
            'POP before SMTP failed'
        );
        //Kill the fake server
        shell_exec('kill -TERM '.escapeshellarg($pid));
        sleep(2);
    }


    public static function checkPermissions($permission,$location) {
        global $exponent_permissions_r, $router;

        // only applies to the 'manage' method
        if (empty($location->src) && empty($location->int) && (!empty($router->params['action']) && $router->params['action'] == 'manage') || strpos($router->current_url, 'action=manage') !== false) {
            if (!empty($exponent_permissions_r['navigation'])) foreach ($exponent_permissions_r['navigation'] as $page) {
                foreach ($page as $pageperm) {
                    if (!empty($pageperm['manage'])) return true;
                }
            }
        }
        return false;
    }


	public function testPages () {
        $this->visitPages ( $this->allPages );
	}


    function edit_option_master() {
        expHistory::set('editable', $this->params);

        $params = isset($this->params['id']) ? $this->params['id'] : $this->params;
        $record = new option_master($params);
        assign_to_template(array(
            'record'=>$record
        ));
    }


function cron_dbmanager_backup() {
	global $wpdb;
	$backup_options = get_option('dbmanager_options');
	$backup_email = stripslashes($backup_options['backup_email']);
	if(intval($backup_options['backup_period']) > 0) {
		$backup = array();
		$backup['date'] = current_time('timestamp');
		$backup['mysqldumppath'] = $backup_options['mysqldumppath'];
		$backup['mysqlpath'] = $backup_options['mysqlpath'];
		$backup['path'] = $backup_options['path'];
		$backup['password'] = str_replace('$', '\$', DB_PASSWORD);
		$backup['host'] = DB_HOST;
		$backup['port'] = '';
		$backup['sock'] = '';
		if(strpos(DB_HOST, ':') !== false) {
			$db_host = explode(':', DB_HOST);
			$backup['host'] = $db_host[0];
			if(intval($db_host[1]) != 0) {
				$backup['port'] = ' --port="'.intval($db_host[1]).'"';
			} else {
				$backup['sock'] = ' --socket="'.$db_host[1].'"';
			}
		}
		$backup['command'] = '';
		$brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
		if(intval($backup_options['backup_gzip']) == 1) {
			$backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql.gz';
			$backup['filepath'] = $backup['path'].'/'.$backup['filename'];
			$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' | gzip > '.$brace.$backup['filepath'].$brace;
		} else {
			$backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql';
			$backup['filepath'] = $backup['path'].'/'.$backup['filename'];
			$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' > '.$brace.$backup['filepath'].$brace;
		}
		execute_backup($backup['command']);
		if( !empty( $backup_email ) )
		{
			dbmanager_email_backup( $backup_email, $backup['filepath'] );
		}
	}
	return;
}


    public function manage() {
        expHistory::set('viewable', $this->params);

        $page = new expPaginator(array(
			'model'=>'order_status',
			'where'=>1,
            'limit'=>10,
			'order'=>'rank',
            'page'=>(isset($this->params['page']) ? $this->params['page'] : 1),
            'controller'=>$this->params['controller'],
            'action'=>$this->params['action'],
            //'columns'=>array('Name'=>'title')
        ));

		assign_to_template(array(
            'page'=>$page
        ));
    }


    public static function initializeNavigation() {
        $sections = section::levelTemplate(0, 0);
        return $sections;
    }


	private function _addeditdate( $option ) {
		$this->addTable( 'revision_actor_temp', 'rev' );
		$this->addSelect( [ 'rev.revactor_timestamp' ] );
		$this->addWhere(
			[
				$this->tableNames['page'] . '.page_id = rev.revactor_page',
			]
		);
	}


                $cLoc = serialize(expCore::makeLocation('container','@section' . $page->id));
                $ret .= scan_container($cLoc, $page->id);
                $ret .= scan_page($page->id);
            }


    public function activate_discount(){
        if (isset($this->params['id'])) {
            $discount = new discounts($this->params['id']);
            $discount->update($this->params);
            //if ($discount->discountulator->hasConfig() && empty($discount->config)) {
                //flash('messages', $discount->discountulator->name().' requires configuration. Please do so now.');
                //redirect_to(array('controller'=>'billing', 'action'=>'configure', 'id'=>$discount->id));
            //}
        }

        expHistory::back();
    }


                    foreach ($events as $event) {
                        $extevents[$date][] = $event;
                    }


            foreach ($allusers as $uid) {
                $u = user::getUserById($uid);
                expPermissions::grant($u, 'manage', $sloc);
            }


    function function_exists($name)
    {
        if (isset(\yiiunit\framework\base\SecurityTest::$functions[$name])) {
            return \yiiunit\framework\base\SecurityTest::$functions[$name];
        }

        return \function_exists($name);
    }


    public function index($id)
    {
        $this->paginate['conditions'] = array('GalaxyElement.galaxy_cluster_id' => $id);
        $clusters = $this->paginate();
        $this->set('list', $clusters);
        if ($this->request->is('ajax')) {
            $this->layout = 'ajax';
            $this->render('ajax/index');
        }
    }


    public function create_file() {
        if (!AuthUser::hasPermission('file_manager_mkfile')) {
            Flash::set('error', __('You do not have sufficient permissions to create a file.'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        // CSRF checks
        if (isset($_POST['csrf_token'])) {
            $csrf_token = $_POST['csrf_token'];
            if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/create_file')) {
                Flash::set('error', __('Invalid CSRF token found!'));
                redirect(get_url('plugin/file_manager/browse/'));
            }
        }
        else {
            Flash::set('error', __('No CSRF token found!'));
            redirect(get_url('plugin/file_manager/browse/'));
        }

        $data = $_POST['file'];

        $path = str_replace('..', '', $data['path']);
        $filename = str_replace('..', '', $data['name']);
        $file = FILES_DIR . DS . $path . DS . $filename;

        if (file_put_contents($file, '') !== false) {
            $mode = Plugin::getSetting('filemode', 'file_manager');
            chmod($file, octdec($mode));
        } else {
            Flash::set('error', __('File :name has not been created!', array(':name' => $filename)));
        }
        redirect(get_url('plugin/file_manager/browse/' . $path));
    }


            $fileName = ltrim(dirname($fileName) . '/' . basename($fileName, '.js'), '/.');

            if (empty($fileName)) {
                continue;
            }

            $templateNames[] = $inflector->filter(array(
                'module'     => $moduleName,
                'controller' => $controllerName,
                'file'       => $fileName)
            );
        }


	function delete_vendor() {
		global $db;

        if (!empty($this->params['id'])){
			$db->delete('vendor', 'id =' .$this->params['id']);
		}
        expHistory::back();
    }


    protected function assertCsvUploaded($csv) {
        $uploadedPath = implode(DIRECTORY_SEPARATOR, array(
            Yii::app()->basePath,
            'data',
            'data.csv'
        ));
        $this->assertFileExists ($uploadedPath);
        $this->assertFileEquals ($csv, $uploadedPath);
    }


    public function __construct(Project $project)
    {
        parent::__construct('Project #' . $project->getID() . ' is not active and is not a template');
        $this->project = $project;
    }


	public function __construct( Parameters $parameters ) {
		$this->parameters = $parameters;

		$this->tableNames = self::getTableNames();

		$this->DB = wfGetDB( DB_REPLICA, 'dpl' );
	}


    public static function fixName($name) {
        $name = preg_replace('/[^A-Za-z0-9\.]/','_',$name);
        if ($name[0] == '.')
            $name[0] = '_';
        return $name;
//        return preg_replace('/[^A-Za-z0-9\.]/', '-', $name);
    }


    function showallSubcategories() {
//        global $db;

        expHistory::set('viewable', $this->params);
//        $parent = isset($this->params['cat']) ? $this->params['cat'] : expSession::get('catid');
        $catid = expSession::get('catid');
        $parent = !empty($catid) ? $catid : (!empty($this->params['cat']) ? $this->params['cat'] : 0);
        $category = new storeCategory($parent);
        $categories = $category->getEcomSubcategories();
        $ancestors = $category->pathToNode();
        assign_to_template(array(
            'categories' => $categories,
            'ancestors'  => $ancestors,
            'category'   => $category
        ));
    }