    public function actionPublishPost() {
        $post = new Events;
        // $user = $this->loadModel($id);
        if (isset($_POST['text']) && $_POST['text'] != "") {
            $post->text = $_POST['text'];
            $post->visibility = $_POST['visibility'];
            if (isset($_POST['associationId']))
                $post->associationId = $_POST['associationId'];
            //$soc->attributes = $_POST['Social'];
            //die(var_dump($_POST['Social']));
            $post->user = Yii::app()->user->getName();
            $post->type = 'feed';
            $post->subtype = $_POST['subtype'];
            $post->lastUpdated = time();
            $post->timestamp = time();
            if ($post->save()) {
                if (!empty($post->associationId) && $post->associationId != Yii::app()->user->getId()) {

                    $notif = new Notification;

                    $notif->type = 'social_post';
                    $notif->createdBy = $post->user;
                    $notif->modelType = 'Profile';
                    $notif->modelId = $post->associationId;

                    $notif->user = Yii::app()->db->createCommand()
                            ->select('username')
                            ->from('x2_users')
                            ->where('id=:id', array(':id' => $post->associationId))
                            ->queryScalar();

                    // $prof = X2Model::model('Profile')->findByAttributes(array('username'=>$post->user));
                    // $notif->text = "$prof->fullName posted on your profile.";
                    // $notif->record = "profile:$prof->id";
                    // $notif->viewed = 0;
                    $notif->createDate = time();
                    // $subject=X2Model::model('Profile')->findByPk($id);
                    // $notif->user = $subject->username;
                    $notif->save();
                }
            }
        }
    }


                $criteria->addCondition (
                    'user IN (' .
                        'SELECT DISTINCT b.username ' .
                        'FROM x2_group_to_user a JOIN x2_group_to_user b ' .
                        'ON a.groupId=b.groupId ' .
                        'WHERE a.username=:getAccessCriteria_username' .
                    ') OR (user = :getAccessCriteria_username)');
            } else { // default history privacy (public or assigned)
                $criteria->addCondition ("(user=:getAccessCriteria_username OR visibility=1)");
            }
        }

        if ($profile) {
            $criteria->params[':getAccessCriteria_profileUsername'] = $profile->username;
            /* only show events associated with current profile which current user has
              permission to see */
            $criteria->addCondition ("user=:getAccessCriteria_profileUsername");
            if (!Yii::app()->params->isAdmin) {
                $criteria->addCondition ("visibility=1");
            }
        }
        return $criteria;
    }

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.


    public function getLayout(){
        $layout = $this->getAttribute('layout');

        $initLayout = $this->initLayout();

        if(!$layout){ // layout hasn't been initialized?
            $layout = $initLayout;
            $this->layout = json_encode($layout);
            $this->update(array('layout'));
        }else{
            $layout = json_decode($layout, true); // json to associative array
            $this->addRemoveLayoutElements('center', $layout, $initLayout);
            $this->addRemoveLayoutElements('left', $layout, $initLayout);
            $this->addRemoveLayoutElements('right', $layout, $initLayout);
        }

        return $layout;
    }

The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.


                    $layout[$loc] = array_merge($layout[$loc],$data);
                }
            }
        }
        return $layout;
    }


    public function beforeSave() {
        if(strpos($this->tag,self::DELIM) !== false) {
            $this->tag = strtr($this->tag,array(self::DELIM => ''));
        }
        return true;
    }


    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();
    }


                    Contacts::model()->deleteAll($criteria);
                }
            }
            echo $model->id;
        }
    }


	public function actionView($id) {
		$model = CActiveRecord::model('Docs')->findByPk($id);
        if (!$this->checkPermissions($model, 'view')) $this->denied ();

		if(isset($model)){
			$permissions=explode(", ",$model->editPermissions);
			if(in_array(Yii::app()->user->getName(),$permissions))
				$editFlag=true;
			else
				$editFlag=false;
		}
		//echo $model->visibility;exit;
		if (!isset($model) ||
			   !(($model->visibility==1 ||
				($model->visibility==0 && $model->createdBy==Yii::app()->user->getName())) ||
				Yii::app()->params->isAdmin|| $editFlag))
			$this->redirect(array('/docs/docs/index'));

        // add doc to user's recent item list
        User::addRecentItem('d', $id, Yii::app()->user->getId());
        X2Flow::trigger('RecordViewTrigger',array('model'=>$model));
		$this->render('view', array(
			'model' => $model,
		));
	}


    public function actionGetItems(){
        $model = X2Model::model ($this->modelClass);
        if (isset ($model)) {
            $tableName = $model->tableName ();
            $sql =
                'SELECT id, fileName as value
                 FROM '.$tableName.'
                 WHERE associationType!="theme" and fileName LIKE :qterm
                 ORDER BY fileName 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 searchAdmin(){
        $criteria = new CDbCriteria;
        return $this->searchBase($criteria);
    }


    public function actionGetItems(){
        $sql = 'SELECT id, name as value FROM x2_x2leads 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);
        Yii::app()->end();
    }


    public static function restoreX2AuthManager () {
        if (isset (self::$_oldAuthManagerComponent)) {
            Yii::app()->setComponent ('authManager', self::$_oldAuthManagerComponent);
        } else {
            throw new CException ('X2AuthManager component could not be restored');
        }
    }


    protected function assertNoPHPErrors () {
		$this->assertElementNotPresent('css=.xdebug-error');
		$this->assertElementNotPresent('css=#x2-php-error');
    }


	public function newModel() {
		return new APIModel('testuser','5f4dcc3b5aa765d61d8327deb882cf99',rtrim(TEST_BASE_URL,'/'));
	}


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


    public function testGetEvents(){
        TestingAuxLib::loadX2NonWebUser ();
        TestingAuxLib::suLogin ('admin');

        Yii::app()->settings->historyPrivacy = null;
        $lastEventId = 0;
        $lastTimestamp = 0;
        $events = Events::getEvents ($lastEventId, $lastTimestamp, 4);
        $this->assertEquals (
            Yii::app()->db->createCommand (
                "select id from x2_events order by timestamp desc, id desc limit 4")
                ->queryColumn (),
            array_map(function ($event) { return $event->id; }, $events['events'])
        );
        TestingAuxLib::restoreX2WebUser ();
    }


    public function testRedirectLinkGeneration () {
        Yii::app()->controller = new MarketingController (
            'campaign', new MarketingModule ('campaign', null));
        $_SERVER['SERVER_NAME'] = 'localhost';
        $cmb = $this->instantiate();
        $contact = $this->contacts('testUser_unsent');
        $campaign = $this->campaign('redirectLinkGeneration');
        $url = preg_replace ('/^[^"]*"([^"]*)".*$/', '$1', $campaign->content);
        list($subject,$message,$uniqueId) = $cmb->prepareEmail(
            $this->campaign('redirectLinkGeneration'),
            $contact,$this->listItem('testUser_unsent')->emailAddress);
        $this->assertRegExp ('/'.preg_quote (urlencode ($url)).'/', $message);

    }


        $k = trim(strtok($val, ':'));
        $v = trim(substr(strstr($val, ':'), 1));

        if ($v == '') continue;

        $hasdata = true;

        if (isset($translate[$k])) {
            $k = $translate[$k];
            if ($k == '') continue;
            if (strstr($k, '.')) {
                eval("\$block" . getvarname($k) . "=\$v;");
                continue;
            }
        } else $k = strtolower($k);

        if ($k == 'handle') {
            $v = strtok($v, ' ');
            $gkey = strtoupper($v);
        }

        if (isset($block[$k]) && is_array($block[$k]))
            $block[$k][] = $v;
        else
            if (!isset($block[$k]) || $block[$k] == '')
                $block[$k] = $v;
            else {
                $x = $block[$k];
                unset($block[$k]);
                $block[$k][] = $x;
                $block[$k][] = $v;
            }
    }

Improper Control of Generation of Code ('Code Injection')

The software constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.


$link_text = wp_get_attachment_image( $_post->ID, $size, $icon, $attr );
	} else {
		$link_text = '';
	}

	if ( trim( $link_text ) == '' )
		$link_text = $_post->post_title;

	/**
	 * Filters a retrieved attachment page link.
	 *
	 * @since 2.7.0
	 *
	 * @param string       $link_html The page link HTML output.
	 * @param int          $id        Post ID.
	 * @param string|array $size      Size of the image. Image size or array of width and height values (in that order).
	 *                                Default 'thumbnail'.
	 * @param bool         $permalink Whether to add permalink to image. Default false.
	 * @param bool         $icon      Whether to include an icon. Default false.
	 * @param string|bool  $text      If string, will be link text. Default false.
	 */
	return apply_filters( 'wp_get_attachment_link', "$link_text", $id, $size, $permalink, $icon, $text );
}


	public function delete_item_permissions_check( $request ) {
		$id      = (int) $request['id'];
		$comment = get_comment( $id );

		if ( ! $comment ) {
			return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) );
		}

		if ( ! $this->check_edit_permission( $comment ) ) {
			return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this comment.' ), array( 'status' => rest_authorization_required_code() ) );
		}
		return true;
	}


    private function __checkIfPulledEventExistsAndAddOrUpdate($event, $eventId, &$successes, &$fails, $eventModel, $server, $user, $jobId)
    {
        // check if the event already exist (using the uuid)
        $existingEvent = $eventModel->find('first', array('conditions' => array('Event.uuid' => $event['Event']['uuid'])));
        $passAlong = $server['Server']['id'];
        if (!$existingEvent) {
            // add data for newly imported events
            $result = $eventModel->_add($event, true, $user, $server['Server']['org_id'], $passAlong, true, $jobId);
            if ($result === true) {
                $successes[] = $eventId;
            } else {
                $fails[$eventId] = __('Failed (partially?) because of errors: ') . $result;
            }
        } else {
            if (!$existingEvent['Event']['locked'] && !$server['Server']['internal']) {
                $fails[$eventId] = __('Blocked an edit to an event that was created locally. This can happen if a synchronised event that was created on this instance was modified by an administrator on the remote side.');
            } else {
                $result = $eventModel->_edit($event, $user, $existingEvent['Event']['id'], $jobId, $passAlong);
                if ($result === true) {
                    $successes[] = $eventId;
                } elseif (isset($result['error'])) {
                    $fails[$eventId] = $result['error'];
                } else {
                    $fails[$eventId] = json_encode($result);
                }
            }
        }
    }

The software does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.


	public function authenticate(CakeRequest $request, CakeResponse $response)
	{
		return self::getUser($request);
	}

The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.


    public function testCreateRelationshipMeta()
    {
        // test
        $GLOBALS['log']->reset();
        SugarBean::createRelationshipMeta(null, null, null, array(), null);
        self::assertCount(1, $GLOBALS['log']->calls['fatal']);

        // test
        $GLOBALS['log']->reset();
        SugarBean::createRelationshipMeta(null, null, null, array(), 'Contacts');
        self::assertCount(1, $GLOBALS['log']->calls['fatal']);

        // test
        $GLOBALS['log']->reset();
        SugarBean::createRelationshipMeta(null, null, null, array(), 'Contacts', true);
        self::assertCount(1, $GLOBALS['log']->calls['fatal']);

        // test
        $GLOBALS['log']->reset();
        SugarBean::createRelationshipMeta('User', null, null, array(), 'Contacts');
        self::assertCount(6, $GLOBALS['log']->calls['fatal']);

        // test
        $GLOBALS['log']->reset();
        SugarBean::createRelationshipMeta('User', $this->db, null, array(), 'Contacts');
        self::assertNotTrue(isset($GLOBALS['log']->calls['fatal']));

        // test
        $GLOBALS['log']->reset();
        SugarBean::createRelationshipMeta('Nonexists1', $this->db, null, array(), 'Nonexists2');
        self::assertCount(1, $GLOBALS['log']->calls['debug']);

        // test
        $GLOBALS['log']->reset();
        SugarBean::createRelationshipMeta('User', null, null, array(), 'Contacts');
        self::assertCount(6, $GLOBALS['log']->calls['fatal']);
    }

Improper Neutralization of Formula Elements in a CSV File

The software saves user-provided information into a Comma-Separated Value (CSV) file, but it does not neutralize or incorrectly neutralizes special elements that could be interpreted as a command when the file is opened by spreadsheet software.


	public function Set($_var = '', $_value = '', $_vartrusted = false, $_valuetrusted = false) {

		if ($_var != ''
			&& $_value != ''
		) {
			if (!$_vartrusted) {
				$_var = strip_tags($_var);
			}

			if (!$_valuetrusted) {
				$_value = strip_tags($_value, '<br />');
			}

			if (strtolower($_var) == 'message'
				|| strtolower($_var) == 'subject'
			) {
				$_value = $this->convertLatin1ToHtml($_value);
			}

			$this->t_data[$_var] = $_value;
		}
	}

Incorrect Permission Assignment for Critical Resource

The product specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors.


	static public function getLastArchived($_num = 10, $_admin = 1) {

		if ($_num > 0) {

			$archived = array();
			$counter = 0;
			$result_stmt = Database::prepare("
				SELECT *, (
					SELECT COUNT(`sub`.`id`)
					FROM `" . TABLE_PANEL_TICKETS . "` `sub`
					WHERE `sub`.`answerto` = `main`.`id`
				) as `ticket_answers`
				FROM `" . TABLE_PANEL_TICKETS . "` `main`
				WHERE `main`.`answerto` = '0' AND `main`.`archived` = '1'
				AND `main`.`adminid` = :adminid
				ORDER BY `main`.`lastchange` DESC LIMIT 0, ".(int)$_num
			);
			Database::pexecute($result_stmt, array('adminid' => $_admin));

			while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {

				$archived[$counter]['id'] = $row['id'];
				$archived[$counter]['customerid'] = $row['customerid'];
				$archived[$counter]['adminid'] = $row['adminid'];
				$archived[$counter]['lastreplier'] = $row['lastreplier'];
				$archived[$counter]['ticket_answers'] = $row['ticket_answers'];
				$archived[$counter]['category'] = $row['category'];
				$archived[$counter]['priority'] = $row['priority'];
				$archived[$counter]['subject'] = $row['subject'];
				$archived[$counter]['message'] = $row['message'];
				$archived[$counter]['dt'] = $row['dt'];
				$archived[$counter]['lastchange'] = $row['lastchange'];
				$archived[$counter]['status'] = $row['status'];
				$archived[$counter]['by'] = $row['by'];
				$counter++;
			}

			if (isset($archived[0]['id'])) {
				return $archived;
			} else {
				return false;
			}
		}


    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 upload() {
        if (!AuthUser::hasPermission('file_manager_upload')) {
            Flash::set('error', __('You do not have sufficient permissions to upload 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/upload')) {
                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/'));
        }

        $mask = Plugin::getSetting('umask', 'file_manager');
        umask(octdec($mask));

        $data = $_POST['upload'];
        $path = str_replace('..', '', $data['path']);
        $overwrite = isset($data['overwrite']) ? true : false;

        // Clean filenames
        $filename = preg_replace('/ /', '_', $_FILES['upload_file']['name']);
        $filename = preg_replace('/[^a-z0-9_\-\.]/i', '', $filename);

        if (isset($_FILES)) {
            $file = $this->_upload_file($filename, FILES_DIR . '/' . $path . '/', $_FILES['upload_file']['tmp_name'], $overwrite);

            if ($file === false)
                Flash::set('error', __('File has not been uploaded!'));
        }
        redirect(get_url('plugin/file_manager/browse/' . $path));
    }


    public function save() {
        $data = $_POST['file'];

        // security (remove all ..)
        $data['name'] = str_replace('..', '', $data['name']);
        $file = FILES_DIR . DS . $data['name'];

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

        if (file_exists($file)) {
            if (file_put_contents($file, $data['content']) !== false) {
                Flash::set('success', __('File has been saved with success!'));
            } else {
                Flash::set('error', __('File is not writable! File has not been saved!'));
            }
        } else {
            if (file_put_contents($file, $data['content'])) {
                Flash::set('success', __('File :name has been created with success!', array(':name' => $data['name'])));
            } else {
                Flash::set('error', __('Directory is not writable! File has not been saved!'));
            }
        }

        // save and quit or save and continue editing ?
        if (isset($_POST['commit'])) {
            redirect(get_url('plugin/file_manager/browse/' . substr($data['name'], 0, strrpos($data['name'], '/'))));
        } else {
            redirect(get_url('plugin/file_manager/view/' . $data['name'] . (endsWith($data['name'], URL_SUFFIX) ? '?has_url_suffix=1' : '')));
        }


    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));
    }


		form_end_row();
		$i++;
	}

	html_end_box(false);

/*
	print "<pre>";
	if (isset($check) && is_array($check)) {
		print_r($check);
	}
	print "</pre>";
*/

}


			form_selectable_cell(filter_value($vdef['name'], get_request_var('filter'), 'vdef.php?action=edit&id=' . $vdef['id']), $vdef['id']);
            form_selectable_cell($disabled ? __('No'):__('Yes'), $vdef['id'], '', 'text-align:right');
            form_selectable_cell(number_format_i18n($vdef['graphs'], '-1'), $vdef['id'], '', 'text-align:right');
            form_selectable_cell(number_format_i18n($vdef['templates'], '-1'), $vdef['id'], '', 'text-align:right');
            form_checkbox_cell($vdef['name'], $vdef['id'], $disabled);
            form_end_row();
        }


				} elseif (!is_numeric($item) && ($item != '')) {
					return false;
				}
			}
		} else {
			return false;
		}
	} else {

The software writes data past the end, or before the beginning, of the intended buffer.


    public function onRouteStartup(Enlight_Controller_EventArgs $args)
    {
        $request = $args->getRequest();

        if (strpos($request->getPathInfo(), '/backend') === 0
            || strpos($request->getPathInfo(), '/api/') === 0
        ) {
            return;
        }

        $shop = $this->getShopByRequest($request);

        if (!$shop->getHost()) {
            $shop->setHost($request->getHttpHost());
        }
        if (!$shop->getBaseUrl()) {
            $preferBasePath = $this->get(Shopware_Components_Config::class)->preferBasePath;
            $shop->setBaseUrl($preferBasePath ? $request->getBasePath() : $request->getBaseUrl());
        }
        if (!$shop->getBasePath()) {
            $shop->setBasePath($request->getBasePath());
        }

        // Read original base path for resources
        $request->getBasePath();
        $request->setBaseUrl($shop->getBaseUrl());

        // Update path info
        $request->setPathInfo(
            $this->createPathInfo($request, $shop)
        );

        if (($host = $request->getHeader('X_FORWARDED_HOST')) !== null
            && $host === $shop->getHost()
        ) {
            // If the base path is null, set it to empty string. Otherwise the request will try to assemble the base path. On a reverse proxy setup with varnish this will fail on virtual URLs like /en
            // The X-Forwarded-Host header is only set in such environments
            if ($shop->getBasePath() === null) {
                $shop->setBasePath('');
            }

            $request->setSecure();
            $request->setBasePath($shop->getBasePath());
            $request->setBaseUrl($shop->getBaseUrl());
            $request->setHttpHost($shop->getHost());
        }

        $this->validateShop($shop);
        $this->get(ShopRegistrationServiceInterface::class)->registerShop($shop);
    }

URL Redirection to Untrusted Site ('Open Redirect')

A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks.


    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);
        }
    }

Weaknesses in this category are related to the design and implementation of data confidentiality and integrity. Frequently these deal with the use of encoding techniques, encryption libraries, and hashing algorithms. The weaknesses in this category could lead to a degradation of the quality data if they are not addressed.


        $module_views[$key]['name'] = gt($value['name']);
    }

    // look for a config form for this module's current view
//    $controller->loc->mod = expModules::getControllerClassName($controller->loc->mod);
    //check to see if hcview was passed along, indicating a hard-coded module
//    if (!empty($controller->params['hcview'])) {
//        $viewname = $controller->params['hcview'];
//    } else {
//        $viewname = $db->selectValue('container', 'view', "internal='".serialize($controller->loc)."'");
//    }
//    $viewconfig = $viewname.'.config';
//    foreach ($modpaths as $path) {
//        if (file_exists($path.'/'.$viewconfig)) {
//            $fileparts = explode('_', $viewname);
//            if ($fileparts[0]=='show'||$fileparts[0]=='showall') array_shift($fileparts);
//            $module_views[$viewname]['name'] = ucwords(implode(' ', $fileparts)).' '.gt('View Configuration');
//            $module_views[$viewname]['file'] =$path.'/'.$viewconfig;
//        }
//    }

    // sort the views highest to lowest by filename
    // we are reverse sorting now so our array merge
    // will overwrite property..we will run array_reverse
    // when we're finished to get them back in the right order
    krsort($common_views);
    krsort($module_views);

    if (!empty($moduleconfig)) $common_views = array_merge($common_views, $moduleconfig);
    $views = array_merge($common_views, $module_views);
    $views = array_reverse($views);

    return $views;
}

Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.


function get_filedisplay_views() {
    expTemplate::get_filedisplay_views();

    $paths = array(
        BASE.'framework/modules/common/views/file/',
        BASE.'themes/'.DISPLAY_THEME.'modules/common/views/file/',
    );

    $views = array();
    foreach ($paths as $path) {
        if (is_readable($path)) {
            $dh = opendir($path);
            while (($file = readdir($dh)) !== false) {
                if (is_readable($path.'/'.$file) && substr($file, -4) == '.tpl' && substr($file, -14) != '.bootstrap.tpl' && substr($file, -15) != '.bootstrap3.tpl' && substr($file, -10) != '.newui.tpl') {
                    $filename = substr($file, 0, -4);
                    $views[$filename] = gt($filename);
                }
            }
        }
    }

    return $views;
}


	function lockTable($table,$lockType="WRITE") {
        $sql = "LOCK TABLES `" . $this->prefix . "$table` $lockType";

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


    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;
    }


    function selectArraysBySql($sql) {
        $res = @mysqli_query($this->connection, $this->injectProof($sql));
        if ($res == null)
            return array();
        $arrays = array();
        for ($i = 0, $iMax = mysqli_num_rows($res); $i < $iMax; $i++)
            $arrays[] = mysqli_fetch_assoc($res);
        return $arrays;
    }


    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;
    }


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

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


    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);
                    }
                }
            }
        }
    }


Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')

The software constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component.


$rst[$key] = self::parseAndTrim($st, $unescape);
            }
            return $rst;
        }

        $str = str_replace("
"," ",$str);
        $str = str_replace("
"," ",$str);
        $str = str_replace("
"," ",$str);
        $str = str_replace("
"," ",$str);
        $str = str_replace("\r\n"," ",$str);
        $str = str_replace('"',""",$str);
        $str = str_replace("'","'",$str);
        $str = str_replace("’","’",$str);
        $str = str_replace("‘","‘",$str);
        $str = str_replace("®","®",$str);
        $str = str_replace("–","-", $str);
        $str = str_replace("—","—", $str);
        $str = str_replace("”","”", $str);
        $str = str_replace("“","“", $str);
        $str = str_replace("¼","¼",$str);
        $str = str_replace("½","½",$str);
        $str = str_replace("¾","¾",$str);
		$str = str_replace("™","™", $str);
		$str = trim($str);

        if ($unescape) {
			$str = stripcslashes($str);
		} else {
	        $str = addslashes($str);
        }

        return $str;
    }


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


static function convertXMLFeedSafeChar($str) {
		$str = str_replace("
","",$str);
        $str = str_replace("
","",$str);
        $str = str_replace("
","",$str);
        $str = str_replace("
","",$str);
        $str = str_replace(""",'"',$str);
        $str = str_replace("'","'",$str);
        $str = str_replace("’","'",$str);
        $str = str_replace("‘","'",$str);
        $str = str_replace("®","",$str);
        $str = str_replace("�","-", $str);
        $str = str_replace("�","-", $str);
        $str = str_replace("�", '"', $str);
        $str = str_replace("”",'"', $str);
        $str = str_replace("�", '"', $str);
        $str = str_replace("“",'"', $str);
        $str = str_replace("\r\n"," ",$str);
        $str = str_replace("�"," 1/4",$str);
        $str = str_replace("¼"," 1/4", $str);
        $str = str_replace("�"," 1/2",$str);
        $str = str_replace("½"," 1/2",$str);
        $str = str_replace("�"," 3/4",$str);
        $str = str_replace("¾"," 3/4",$str);
        $str = str_replace("�", "(TM)", $str);
        $str = str_replace("™","(TM)", $str);
        $str = str_replace("®","(R)", $str);
        $str = str_replace("�","(R)",$str);
        $str = str_replace("&","&",$str);
		$str = str_replace(">",">",$str);
        return trim($str);
	}


    public function manage()
    {
        expHistory::set('manageable',$this->params);
        $gc = new geoCountry();
        $countries = $gc->find('all');

        $gr = new geoRegion();
        $regions = $gr->find('all',null,'rank asc,name asc');

        assign_to_template(array(
            'countries'=>$countries,
            'regions'=>$regions
        ));
    }


    public function activate_address()
    {
        global $db, $user;

        $object = new stdClass();
        $object->id = $this->params['id'];
        $db->setUniqueFlag($object, 'addresses', $this->params['is_what'], "user_id=" . $user->id);
        flash("message", gt("Successfully updated address."));
        expHistory::back();
    }


	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();
	}


    function reset_stats() {
//        global $db;

        // reset the counters
//        $db->sql ('UPDATE '.$db->prefix.'banner SET impressions=0 WHERE 1');
        banner::resetImpressions();
//        $db->sql ('UPDATE '.$db->prefix.'banner SET clicks=0 WHERE 1');
        banner::resetClicks();

        // let the user know we did stuff.
        flash('message', gt("Banner statistics reset."));
        expHistory::back();
    }


	function edit() {
	    if (empty($this->params['content_id'])) {
	        flash('message',gt('An error occurred: No content id set.'));
            expHistory::back();
	    }
        /* The global constants can be overridden 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'];

	    $id = empty($this->params['id']) ? null : $this->params['id'];
	    $comment = new expComment($id);
        //FIXME here is where we might sanitize the comment before displaying/editing it
		assign_to_template(array(
		    'content_id'=>$this->params['content_id'],
            'content_type'=>$this->params['content_type'],
		    'comment'=>$comment
		));
	}


            $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 approve_toggle() {
        global $history;

        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']) ? 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'];

        $simplenote = new expSimpleNote($this->params['id']);
        $simplenote->approved = $simplenote->approved == 1 ? 0 : 1;
        $simplenote->save();

        $lastUrl = makelink($history->history[$history->history['lasts']['type']][count($history->history[$history->history['lasts']['type']])-1]['params']);
        if (!empty($this->params['tab']))
        {
            $lastUrl .= "#".$this->params['tab'];
        }
        redirect_to($lastUrl);
    }


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

        /* 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('No ID supplied for note to approve'));
            $lastUrl = expHistory::getLast('editable');
        }

        $simplenote = new expSimpleNote($this->params['id']);
        assign_to_template(array(
            'simplenote'=>$simplenote,
            'require_login'=>$require_login,
            'require_approval'=>$require_approval,
            'require_notification'=>$require_notification,
            'notification_email'=>$notification_email,
            'tab'=>$this->params['tab']
        ));
    }


    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 approve_submit() {
        global $history;

        if (empty($this->params['id'])) {
            flash('error', gt('No ID supplied for comment to approve'));
            $lastUrl = expHistory::getLast('editable');
        }

        /* 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'];

        $simplenote = new expSimpleNote($this->params['id']);
        //FIXME here is where we might sanitize the note before approving it
        $simplenote->body = $this->params['body'];
        $simplenote->approved = $this->params['approved'];
        $simplenote->save();

        $lastUrl = makelink($history->history[$history->history['lasts']['type']][count($history->history[$history->history['lasts']['type']])-1]['params']);
        if (!empty($this->params['tab']))
        {
            $lastUrl .= "#".$this->params['tab'];
        }
        redirect_to($lastUrl);
    }


            $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();
    }


    public function confirm() {
        global $db;

        // 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
        $id = $db->selectValue('subscribers','id', 'id='.$this->params['id'].' AND hash="'.$this->params['key'].'"');
        if (empty($id)) expQueue::flashAndFlow('error', gt('We could not find any subscriptions matching the ID and Key you provided.'));

        // activate this users pending subscriptions
        $sub = new stdClass();
        $sub->enabled = 1;
        $db->updateObject($sub, 'expeAlerts_subscribers', 'subscribers_id='.$id);

        // find the users active subscriptions
        $ealerts = expeAlerts::getBySubscriber($id);
        assign_to_template(array(
            'ealerts'=>$ealerts
        ));
    }


    public function pending() {
//        global $db;

        // make sure we have what we need.
        if (empty($this->params['id'])) expQueue::flashAndFlow('error', gt('Your subscriber ID was not supplied.'));

        // find the subscriber and their pending subscriptions
        $ealerts = expeAlerts::getPendingBySubscriber($this->params['id']);
        $subscriber = new subscribers($this->params['id']);

        // render the template
        assign_to_template(array(
            'subscriber'=>$subscriber,
            'ealerts'=>$ealerts
        ));
    }


    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')
        ));
    }


	function manage() {
	    global $db;

	    expHistory::set('manageable', $this->params);
//	    $classes = array();
        $dir = BASE."framework/modules/ecommerce/billingcalculators";
        if (is_readable($dir)) {
            $dh = opendir($dir);
            while (($file = readdir($dh)) !== false) {
                if (is_file("$dir/$file") && substr("$dir/$file", -4) == ".php") {
                    include_once("$dir/$file");
                    $classname = substr($file, 0, -4);
                    $id = $db->selectValue('billingcalculator', 'id', 'calculator_name="'.$classname.'"');
                    if (empty($id)) {
//                        $calobj = null;
                        $calcobj = new $classname();
                        if ($calcobj->isSelectable() == true) {
                            $obj = new billingcalculator(array(
                                'title'=>$calcobj->name(),
//                                'user_title'=>$calcobj->title,
                                'body'=>$calcobj->description(),
                                'calculator_name'=>$classname,
                                'enabled'=>false));
                            $obj->save();
                        }
                    }
                }
            }
        }

        $bcalc = new billingcalculator();
        $calculators = $bcalc->find('all');
        assign_to_template(array(
            'calculators'=>$calculators
        ));
	}


	public function update_groupdiscounts() {
	    global $db;

	    if (empty($this->params['id'])) {
	        // look for existing discounts for the same group
	        $existing_id = $db->selectValue('groupdiscounts', 'id', 'group_id='.$this->params['group_id']);
	        if (!empty($existing_id)) flashAndFlow('error',gt('There is already a discount for that group.'));
	    }

        $gd = new groupdiscounts();
	    $gd->update($this->params);
	    expHistory::back();
	}


            $masteroption->delete();
        }

        // delete the mastergroup
        $db->delete('optiongroup', 'optiongroup_master_id='.$mastergroup->id);
        $mastergroup->delete();

        expHistory::back();
    }


    function configure() {
        expHistory::set('editable', $this->params);
        // little bit of trickery so that that categories can have their own configs

        $this->loc->src = "@globalstoresettings";
        $config = new expConfig($this->loc);
        $this->config = $config->config;
        $pullable_modules = expModules::listInstalledControllers($this->baseclassname, $this->loc);
        $views = expTemplate::get_config_templates($this, $this->loc);

        $gc = new geoCountry();
        $countries = $gc->find('all');

        $gr = new geoRegion();
        $regions = $gr->find('all');

        assign_to_template(array(
            'config'=>$this->config,
            'pullable_modules'=>$pullable_modules,
            'views'=>$views,
            'countries'=>$countries,
            'regions'=>$regions,
            'title'=>static::displayname()
        ));
    }


    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 update_option_master() {
        global $db;

        $id = empty($this->params['id']) ? null : $this->params['id'];
        $opt = new option_master($id);
        $oldtitle = $opt->title;

        $opt->update($this->params);

        // if the title of the master changed we should update the option groups that are already using it.
        if ($oldtitle != $opt->title) {

        }$db->sql('UPDATE '.$db->prefix.'option SET title="'.$opt->title.'" WHERE option_master_id='.$opt->id);

        expHistory::back();
    }


	 function manage_upcharge() {
		$this->loc->src = "@globalstoresettings";
        $config = new expConfig($this->loc);
		$this->config = $config->config;

		$gc = new geoCountry();
        $countries = $gc->find('all');

        $gr = new geoRegion();
        $regions = $gr->find('all',null,'rank asc,name asc');
        assign_to_template(array(
            'countries'=>$countries,
            'regions'=>$regions,
            'upcharge'=>!empty($this->config['upcharge'])?$this->config['upcharge']:''
        ));
	 }


	 function update_upcharge() {
        $this->loc->src = "@globalstoresettings";
        $config = new expConfig($this->loc);
		$this->config = $config->config;

		//This will make sure that only the country or region that given a rate value will be saved in the db
		$upcharge = array();
		foreach($this->params['upcharge'] as $key => $item) {
			if(!empty($item)) {
				$upcharge[$key] = $item;
			}
		}
		$this->config['upcharge'] = $upcharge;

        $config->update(array('config'=>$this->config));
        flash('message', gt('Configuration updated'));
        expHistory::back();
    }


    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
        ));
    }


    public function search_external() {
//        global $db, $user;
        global $db;

        $sql = "select DISTINCT(a.id) as id, a.source as source, a.firstname as firstname, a.middlename as middlename, a.lastname as lastname, a.organization as organization, a.email as email ";
        $sql .= "from " . $db->prefix . "external_addresses as a "; //R JOIN " .
        //$db->prefix . "billingmethods as bm ON bm.addresses_id=a.id ";
        $sql .= " WHERE match (a.firstname,a.lastname,a.email,a.organization) against ('" . $this->params['query'] .
            "*' IN BOOLEAN MODE) ";
        $sql .= "order by match (a.firstname,a.lastname,a.email,a.organization)  against ('" . $this->params['query'] . "*' IN BOOLEAN MODE) ASC LIMIT 12";
        $res = $db->selectObjectsBySql($sql);
        foreach ($res as $key=>$record) {
            $res[$key]->title = $record->firstname . ' ' . $record->lastname;
        }
        //eDebug($sql);
        $ar = new expAjaxReply(200, gt('Here\'s the items you wanted'), $res);
        $ar->send();
    }


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

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

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


	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);
	}


	function manage_vendors () {
	    expHistory::set('viewable', $this->params);
		$vendor = new vendor();

		$vendors = $vendor->find('all');
		assign_to_template(array(
            'vendors'=>$vendors
        ));
	}


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

		$vendor = new vendor();
		$vendors = $vendor->find('all');
		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');
		}

		assign_to_template(array(
            'purchase_orders'=>$purchase_orders,
            'vendors' => $vendors,
            'vendor_id' => @$this->params['vendor']
        ));
	}


    public function saveconfig() {
        global $db;

        if (empty($this->params['id'])) return false;
        $calcname = $db->selectValue('shippingcalculator', 'calculator_name', 'id='.$this->params['id']);
        $calc = new $calcname($this->params['id']);
        $conf = serialize($calc->parseConfig($this->params));
        $calc->update(array('config'=>$conf));
        expHistory::back();
    }


    function manage() {
        expHistory::set('viewable', $this->params);
        //         $category = new storeCategory();
        //         $categories = $category->getFullTree();
        //
        //         // foreach($categories as $i=>$val){
        //         //  if (!empty($this->values) && in_array($val->id,$this->values)) {
        //         //      $this->tags[$i]->value = true;
        //         //  } else {
        //         //      $this->tags[$i]->value = false;
        //         //  }
        //         //  $this->tags[$i]->draggable = $this->draggable;
        //         //  $this->tags[$i]->checkable = $this->checkable;
        //         // }
        //
        // $obj = json_encode($categories);
    }


    static function displayname() {
        return gt("e-Commerce Category Manager");
    }


    static function description() {
        return gt("This module is for managing categories in your store.");
    }


    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 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();
    }


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


    function edit() {
        global $template;

        parent::edit();
        $allforms = array();
        $allforms[""] = gt('Disallow Feedback');
        // calculate which event date is the one being edited
        $event_key = 0;
        foreach ($template->tpl->tpl_vars['record']->value->eventdate as $key=>$d) {
       	    if ($d->id == $this->params['date_id']) $event_key = $key;
       	}

        assign_to_template(array(
            'allforms'     => array_merge($allforms, expTemplate::buildNameList("forms", "event/email", "tpl", "[!_]*")),
            'checked_date' => !empty($this->params['date_id']) ? $this->params['date_id'] : null,
            'event_key'    => $event_key,
        ));
    }


    function delete_recurring() {
        $item = $this->event->find('first', 'id=' . $this->params['id']);
        if ($item->is_recurring == 1) { // need to give user options
            expHistory::set('editable', $this->params);
            assign_to_template(array(
                'checked_date' => $this->params['date_id'],
                'event'        => $item,
            ));
        } else { // Process a regular delete
            $item->delete();
        }
    }


    function import() {
        $pullable_modules = expModules::listInstalledControllers($this->baseclassname);
        $modules = new expPaginator(array(
            'records' => $pullable_modules,
            'controller' => $this->loc->mod,
            'action' => $this->params['action'],
            'order'   => isset($this->params['order']) ? $this->params['order'] : 'section',
            'dir'     => isset($this->params['dir']) ? $this->params['dir'] : '',
            'page'    => (isset($this->params['page']) ? $this->params['page'] : 1),
            'columns' => array(
                gt('Title') => 'title',
                gt('Page')  => 'section'
            ),
        ));

        assign_to_template(array(
            'modules' => $modules,
        ));
    }


    function searchName() {
        return gt("Calendar Event");
    }


                        foreach ($days as $value) {
                            $regitem[] = $value;
                        }


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


            $date->delete(); // event automatically deleted if all assoc eventdates are deleted
        }
        expHistory::back();
    }


            $evs = $this->event->find('all', "id=" . $edate->event_id . $featuresql);
            foreach ($evs as $key=>$event) {
                if ($condense) {
                    $eventid = $event->id;
                    $multiday_event = array_filter($events, create_function('$event', 'global $eventid; return $event->id === $eventid;'));
                    if (!empty($multiday_event)) {
                        unset($evs[$key]);
                        continue;
                    }
                }
                $evs[$key]->eventstart += $edate->date;
                $evs[$key]->eventend += $edate->date;
                $evs[$key]->date_id = $edate->id;
                if (!empty($event->expCat)) {
                    $catcolor = empty($event->expCat[0]->color) ? null : trim($event->expCat[0]->color);
//                    if (substr($catcolor,0,1)=='#') $catcolor = '" style="color:'.$catcolor.';';
                    $evs[$key]->color = $catcolor;
                }
            }
            if (count($events) < 500) {  // magic number to not crash loop?
                $events = array_merge($events, $evs);
            } else {
//                $evs[$key]->title = gt('Too many events to list').', '.(count($edates)-count($events)).' '.gt('not displayed!');
//                $events = array_merge($events, $evs);
                flash('notice',gt('Too many events to list').', '.(count($edates)-count($events)).' '.gt('not displayed!'));
                break; // keep from breaking system by too much data
            }
        }


                        $body = str_replace(array("\n"), "<br />", $body);
                    } else {
                        // It's going elsewhere (doesn't like quoted-printable)
                        $body = str_replace(array("\n"), " -- ", $body);
                    }
                    $title = $items[$i]->title;

                    $msg .= "BEGIN:VEVENT\n";
                    $msg .= $dtstart . $dtend;
                    $msg .= "UID:" . $items[$i]->date_id . "\n";
                    $msg .= "DTSTAMP:" . date("Ymd\THis", time()) . "Z\n";
                    if ($title) {
                        $msg .= "SUMMARY:$title\n";
                    }
                    if ($body) {
                        $msg .= "DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" . $body . "\n";
                    }
                    //	if($link_url) { $msg .= "URL: $link_url\n";}
                    if (!empty($this->config['usecategories'])) {
                        if (!empty($items[$i]->expCat[0]->title)) {
                            $msg .= "CATEGORIES:".$items[$i]->expCat[0]->title."\n";
                        } else {
                            $msg .= "CATEGORIES:".$this->config['uncat']."\n";
                        }
                    }
                    $msg .= "END:VEVENT\n";
                }


    function send_feedback() {
        $success = false;
        if (isset($this->params['id'])) {
            $ed = new eventdate($this->params['id']);
//            $email_addrs = array();
            if ($ed->event->feedback_email != '') {
                $msgtemplate = expTemplate::get_template_for_action($this, 'email/_' . $this->params['formname'], $this->loc);
                $msgtemplate->assign('params', $this->params);
                $msgtemplate->assign('event', $ed);
                $email_addrs = explode(',', $ed->event->feedback_email);
                //This is an easy way to remove duplicates
                $email_addrs = array_flip(array_flip($email_addrs));
                $email_addrs = array_map('trim', $email_addrs);
                $mail = new expMail();
                $success += $mail->quickSend(array(
                    "text_message" => $msgtemplate->render(),
                    'to'           => $email_addrs,
                    'from'         => !empty($this->params['email']) ? $this->params['email'] : trim(SMTP_FROMADDRESS),
                    'subject'      => $this->params['subject'],
                ));
            }
        }

        if ($success) {
            flashAndFlow('message', gt('Your feedback was successfully sent.'));
        } else {
            flashAndFlow('error', gt('We could not send your feedback.  Please contact your administrator.'));
        }
    }


    static function description() {
        return "Manage events and schedules, and optionally publish them.";
    }


    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;
    }


                        foreach ($days as $event) {
                            if (empty($event->eventdate->date) || ($viewrange == 'upcoming' && $event->eventdate->date < time()))
                                break;
                            if (empty($event->eventstart))
                                $event->eventstart = $event->eventdate->date;
                            $extitem[] = $event;
                        }


                foreach ($grpusers as $u) {
                    $emails[$u->email] = trim(user::getUserAttribution($u->id));
                }


    public function buildControl() {
        $control = new colorcontrol();
        if (!empty($this->params['value'])) $control->value = $this->params['value'];
        if ($this->params['value'][0] != '#') $this->params['value'] = '#' . $this->params['value'];
        $control->default = $this->params['value'];
        if (!empty($this->params['hide'])) $control->hide = $this->params['hide'];
        if (isset($this->params['flip'])) $control->flip = $this->params['flip'];
        $this->params['name'] = !empty($this->params['name']) ? $this->params['name'] : '';
        $control->name  = $this->params['name'];
        $this->params['id'] = !empty($this->params['id']) ? $this->params['id'] : '';
        $control->id  = isset($this->params['id']) && $this->params['id'] != "" ? $this->params['id'] : "";
        //echo $control->id;
        if (empty($control->id)) $control->id = $this->params['name'];
        if (empty($control->name)) $control->name = $this->params['id'];

        // attempt to translate the label
        if (!empty($this->params['label'])) {
            $this->params['label'] = gt($this->params['label']);
        } else {
            $this->params['label'] = null;
        }
        echo $control->toHTML($this->params['label'], $this->params['name']);
//        $ar = new expAjaxReply(200, gt('The control was created'), json_encode(array('data'=>$code)));
//        $ar->send();
    }


    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 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!'));
        }
    }


    public function get_view_config() {
        global $template;

        // set paths we will search in for the view
        $paths = array(
            BASE.'themes/'.DISPLAY_THEME.'/modules/common/views/file/configure',
            BASE.'framework/modules/common/views/file/configure',
        );

        foreach ($paths as $path) {
            $view = $path.'/'.$this->params['view'].'.tpl';
            if (is_readable($view)) {
                if (bs(true)) {
                    $bstrapview = $path.'/'.$this->params['view'].'.bootstrap.tpl';
                    if (file_exists($bstrapview)) {
                        $view = $bstrapview;
                    }
                }
                if (bs3(true)) {
                    $bstrapview = $path.'/'.$this->params['view'].'.bootstrap3.tpl';
                    if (file_exists($bstrapview)) {
                        $view = $bstrapview;
                    }
                }
                $template = new controllertemplate($this, $view);
                $ar = new expAjaxReply(200, 'ok');
		        $ar->send();
            }
        }
    }


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


    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);
    }


    public function downloadfile() {
        if (empty($this->params['fileid'])) {
            flash('error', gt('There was an error while trying to download your file.  No File Specified.'));
            expHistory::back();
        }

        $fd = new filedownload($this->params['fileid']);
        if (empty($this->params['filenum'])) $this->params['filenum'] = 0;

        if (empty($fd->expFile['downloadable'][$this->params['filenum']]->id)) {
            flash('error', gt('There was an error while trying to download your file.  The file you were looking for could not be found.'));
            expHistory::back();
        }

        $fd->downloads++;
        $fd->save();

        // this will set the id to the id of the actual file..makes the download go right.
        $this->params['id'] = $fd->expFile['downloadable'][$this->params['filenum']]->id;
        parent::downloadfile();
    }


	public function update_version() {
	    // get the current version
	    $hv = new help_version();
	    $current_version = $hv->find('first', 'is_current=1');

	    // check to see if the we have a new current version and unset the old current version.
	    if (!empty($this->params['is_current'])) {
//	        $db->sql('UPDATE '.DB_TABLE_PREFIX.'_help_version set is_current=0');
            help_version::clearHelpVersion();
	    }
	    expSession::un_set('help-version');

	    // save the version
	    $id = empty($this->params['id']) ? null : $this->params['id'];
	    $version = new help_version();
	    // if we don't have a current version yet so we will force this one to be it
	    if (empty($current_version->id)) $this->params['is_current'] = 1;
	    $version->update($this->params);

	    // if this is a new version we need to copy over docs
	    if (empty($id)) {
	        self::copydocs($current_version->id, $version->id);
	    }
        // let's update the search index to reflect the current help version
        searchController::spider();

	    flash('message', gt('Saved help version').' '.$version->version);
	    expHistory::back();
	}


    public static function getHelpVersionId($version) {
        global $db;

        return $db->selectValue('help_version', 'id', 'version="'.$version.'"');
    }


    public static function getHelpVersion($version_id) {
        global $db;

        return $db->selectValue('help_version', 'version', 'id="'.$version_id.'"');
    }


    function remove() {
        global $db;

        $section = $db->selectObject('section', 'id=' . $this->params['id']);
        if ($section) {
            section::removeLevel($section->id);
            $db->decrement('section', 'rank', 1, 'rank > ' . $section->rank . ' AND parent=' . $section->parent);
            $section->parent = -1;
            $db->updateObject($section, 'section');
            expSession::clearAllUsersSessionCache('navigation');
            expHistory::back();
        } else {
            notfoundController::handle_not_authorized();
        }
    }


                foreach ($page as $pageperm) {
                    if (!empty($pageperm['manage'])) return true;
                }


                    $db->updateObject($value, 'section');
                }
                $db->updateObject($moveSec, 'section');
                //handle re-ranking of previous parent
                $oldSiblings = $db->selectObjects("section", "parent=" . $oldParent . " AND rank>" . $oldRank . " ORDER BY rank");
                $rerank      = 1;
                foreach ($oldSiblings as $value) {
                    if ($value->id != $moveSec->id) {
                        $value->rank = $rerank;
                        $db->updateObject($value, 'section');
                        $rerank++;
                    }
                }
                if ($oldParent != $moveSec->parent) {
                    //we need to re-rank the children of the parent that the moving section has just left
                    $childOfLastMove = $db->selectObjects("section", "parent=" . $oldParent . " ORDER BY rank");
                    for ($i = 0, $iMax = count($childOfLastMove); $i < $iMax; $i++) {
                        $childOfLastMove[$i]->rank = $i;
                        $db->updateObject($childOfLastMove[$i], 'section');
                    }
                }
            }
        }
        self::checkForSectionalAdmins($move);
        expSession::clearAllUsersSessionCache('navigation');
    }


            $navs[$i]->link = expCore::makeLink(array('section' => $navs[$i]->id), '', $navs[$i]->sef_name);
            if (!$view) {
//                unset($navs[$i]);  //FIXME this breaks jstree if we remove a parent and not the child
                $attr = new stdClass();
                $attr->class = 'hidden';  // bs3 class to hide elements
                $navs[$i]->li_attr = $attr;
            }
        }


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


    function process_subsections($parent_section, $subtpl) {
        global $db, $router;

        $section              = new stdClass();
        $section->parent      = $parent_section->id;
        $section->name        = $subtpl->name;
        $section->sef_name    = $router->encode($section->name);
        $section->subtheme    = $subtpl->subtheme;
        $section->active      = $subtpl->active;
        $section->public      = $subtpl->public;
        $section->rank        = $subtpl->rank;
        $section->page_title  = $subtpl->page_title;
        $section->keywords    = $subtpl->keywords;
        $section->description = $subtpl->description;
        $section->id          = $db->insertObject($section, 'section');
        self::process_section($section, $subtpl);
    }


            $sloc = expCore::makeLocation('navigation', null, $section->id);
            // remove any manage permissions for this page and it's children
            // $db->delete('userpermission', "module='navigationController' AND internal=".$section->id);
            // $db->delete('grouppermission', "module='navigationController' AND internal=".$section->id);
            foreach ($allusers as $uid) {
                $u = user::getUserById($uid);
                expPermissions::grant($u, 'manage', $sloc);
            }
            foreach ($allgroups as $gid) {
                $g = group::getGroupById($gid);
                expPermissions::grantGroup($g, 'manage', $sloc);
            }
        }
    }


    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 reparent_standalone() {
        $standalone = $this->section->find($this->params['page']);
        if ($standalone) {
            $standalone->parent = $this->params['parent'];
            $standalone->update();
            expSession::clearAllUsersSessionCache('navigation');
            expHistory::back();
        } else {
            notfoundController::handle_not_found();
        }
    }


$link = str_replace(URL_FULL, '', makeLink(array('section' => $section->id)));


    public function showall() {
        global $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(
            'sections'     => $navsections,
            'current'      => $current,
            'canManage'    => ((isset($user->is_acting_admin) && $user->is_acting_admin == 1) ? 1 : 0),
        ));
    }


    public static function DragnDropReRank2() {
        global $router, $db;

        $id = $router->params['id'];
        $page = new section($id);
        $old_rank = $page->rank;
        $old_parent = $page->parent;
        $new_rank = $router->params['position'] + 1;  // rank
        $new_parent = intval($router->params['parent']);

        $db->decrement($page->tablename, 'rank', 1, 'rank>' . $old_rank . ' AND parent=' . $old_parent);  // close in hole
        $db->increment($page->tablename, 'rank', 1, 'rank>=' . $new_rank . ' AND parent=' . $new_parent);  // make room

        $params = array();
        $params['parent'] = $new_parent;
        $params['rank'] = $new_rank;
        $page->update($params);

        self::checkForSectionalAdmins($id);
        expSession::clearAllUsersSessionCache('navigation');
    }


            $loc = expCore::makeLocation('navigation', '', $standalone->id);
            if (expPermissions::check('manage', $loc)) return true;
        }
        return false;
    }


    public static function isPublic($s) {
        if ($s == null) {
            return false;
        }
        while ($s->public && $s->parent > 0) {
            $s = new section($s->parent);
        }
        $lineage = (($s->public) ? 1 : 0);
        return $lineage;
    }


    function edit_freeform() {
        $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(),
        ));
    }


    public static function returnChildrenAsJSON() {
        global $db;

        //$nav = section::levelTemplate(intval($_REQUEST['id'], 0));
        $id         = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
        $nav        = $db->selectObjects('section', 'parent=' . $id, 'rank');
        //FIXME $manage_all is moot w/ cascading perms now?
        $manage_all = false;
        if (expPermissions::check('manage', expCore::makeLocation('navigation', '', $id))) {
            $manage_all = true;
        }
        //FIXME recode to use foreach $key=>$value
        $navcount = count($nav);
        for ($i = 0; $i < $navcount; $i++) {
            if ($manage_all || expPermissions::check('manage', expCore::makeLocation('navigation', '', $nav[$i]->id))) {
                $nav[$i]->manage = 1;
                $view = true;
            } else {
                $nav[$i]->manage = 0;
                $view = $nav[$i]->public ? true : expPermissions::check('view', expCore::makeLocation('navigation', '', $nav[$i]->id));
            }
            $nav[$i]->link = expCore::makeLink(array('section' => $nav[$i]->id), '', $nav[$i]->sef_name);
            if (!$view) unset($nav[$i]);
        }
        $nav= array_values($nav);
//        $nav[$navcount - 1]->last = true;
        if (count($nav)) $nav[count($nav) - 1]->last = true;
//        echo expJavascript::ajaxReply(201, '', $nav);
        $ar = new expAjaxReply(201, '', $nav);
        $ar->send();
    }


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


function searchName() { return gt('Webpage'); }


                $section = new section(intval($page));
                if ($section) {
//                    self::deleteLevel($section->id);
                    $section->delete();
                }
            }
        }


    function edit_section() {
        global $db, $user;

        $parent = new section($this->params['parent']);
        if (empty($parent->id)) $parent->id = 0;
        assign_to_template(array(
            'haveStandalone'  => ($db->countObjects('section', 'parent=-1') && $parent->id >= 0),
            'parent'          => $parent,
            'isAdministrator' => $user->isAdmin(),
        ));
    }


static function isSearchable() { return true; }


    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),
        ));
    }


    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 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;
    }


            $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();
        }
    }


                return $fa->nameGlyph($icons, 'icon-');
            }
        } else {
            return array();
        }
    }


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


    public function breadcrumb() {
        global $sectionObj;

        expHistory::set('viewable', $this->params);
        $id      = $sectionObj->id;
        $current = null;
        // Show not only the location of a page in the hierarchy but also the location of a standalone page
        $current = new section($id);
        if ($current->parent == -1) {  // standalone page
            $navsections = section::levelTemplate(-1, 0);
            foreach ($navsections as $section) {
                if ($section->id == $id) {
                    $current = $section;
                    break;
                }
            }
        } else {
            $navsections = section::levelTemplate(0, 0);
            foreach ($navsections as $section) {
                if ($section->id == $id) {
                    $current = $section;
                    break;
                }
            }
        }
        assign_to_template(array(
            'sections'     => $navsections,
            'current'      => $current,
        ));
    }


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

        // setup the where clause for looking up records.
        $where = parent::aggregateWhereClause();
        $where = "((unpublish != 0 AND unpublish < ".time().") OR (publish > ".time().")) AND ".$where;
        if (isset($this->config['only_featured'])) $where .= ' AND is_featured=1';

        $page = new expPaginator(array(
            'model'=>'news',
            'where'=>$where,
            'limit'=>25,
            'order'=>'unpublish',
            'page'=>(isset($this->params['page']) ? $this->params['page'] : 1),
            'controller'=>$this->baseclassname,
            'action'=>$this->params['action'],
            'src'=>$this->loc->src,
            'columns'=>array(
                gt('Title')=>'title',
                gt('Published On')=>'publish',
                gt('Status')=>'unpublish'
            ),
        ));

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


    public function showall_tags() {
        $images = $this->image->find('all');
        $used_tags = array();
        foreach ($images as $image) {
            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;
                }

            }
        }

        assign_to_template(array(
            'tags'=>$used_tags
        ));
    }


    public function showall() {
        expHistory::set('viewable', $this->params);
        $limit = (isset($this->config['limit']) && $this->config['limit'] != '') ? $this->config['limit'] : 10;
        if (!empty($this->params['view']) && ($this->params['view'] == 'showall_accordion' || $this->params['view'] == 'showall_tabbed')) {
            $limit = '0';
        }
        $order = isset($this->config['order']) ? $this->config['order'] : "rank";
        $page = new expPaginator(array(
            'model'=>'photo',
            'where'=>$this->aggregateWhereClause(),
            'limit'=>$limit,
            'order'=>$order,
            'categorize'=>empty($this->config['usecategories']) ? false : $this->config['usecategories'],
            'uncat'=>!empty($this->config['uncat']) ? $this->config['uncat'] : gt('Not Categorized'),
            'groups'=>!isset($this->params['gallery']) ? array() : array($this->params['gallery']),
            'grouplimit'=>!empty($this->params['view']) && $this->params['view'] == 'showall_galleries' ? 1 : null,
            'page'=>(isset($this->params['page']) ? $this->params['page'] : 1),
            'controller'=>$this->baseclassname,
            'action'=>$this->params['action'],
            'src'=>$this->loc->src,
            'columns'=>array(
                gt('Title')=>'title'
            ),
        ));

        assign_to_template(array(
            'page'=>$page,
            'params'=>$this->params,
        ));
    }