DonatShell
Server IP : 180.180.241.3  /  Your IP : 216.73.216.194
Web Server : Microsoft-IIS/7.5
System : Windows NT NETWORK-NHRC 6.1 build 7601 (Windows Server 2008 R2 Standard Edition Service Pack 1) i586
User : IUSR ( 0)
PHP Version : 5.3.28
Disable Function : NONE
MySQL : ON  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  C:/AppServ/www/app/Controller/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME SHELL ]     

Current File : C:/AppServ/www/app/Controller/PagesController.php_bk-16-9-63
<?php
/**
 * Static content controller.
 *
 * This file will render views from views/pages/
 *
 * PHP 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */
App::uses('AppController', 'Controller');

/**
 * Static content controller
 *
 * Override this controller by placing a copy in controllers directory of an application
 *
 * @package       app.Controller
 * @link http://book.cakephp.org/2.0/en/controllers/pages-controller.html
 */
class PagesController extends AppController {

/**
 * This controller does not use a model
 *
 * @var array
 */
    public $uses = array();

    /**
     * Auth Login configuration
     *
     * @author  Mike <michael.damoiseau@gmail.com>
     * @since  2013-11-13
     */
    public function beforeFilter() {
        $this->Auth->allow(
            'index',
            'regions',
            'provinces',
            'chartProvince',
            'chartRegion',
            'chartCountry',
            'contact',
            'reports_organizations',
            'reports_people',
            'reports_activities',
            'allinfo_reports_people',
            'allinfo_reports_activities',
            'allinfo_reports_organizations',
            'rss_feed');
    }

    /**
     * Displays a view
     *
     * @param mixed What page to display
     * @return void
     * @throws NotFoundException When the view file could not be found
     *  or MissingViewException in debug mode.
     */
    public function display() {
        $path = func_get_args();

        $count = count($path);
        if (!$count) {
            return $this->redirect('/');
        }
        $page = $subpage = $title_for_layout = null;

        if (!empty($path[0])) {
            $page = $path[0];
        }
        if (!empty($path[1])) {
            $subpage = $path[1];
        }
        if (!empty($path[$count - 1])) {
            $title_for_layout = Inflector::humanize($path[$count - 1]);
        }
        $this->set(compact('page', 'subpage', 'title_for_layout'));

        try {
            $this->render(implode('/', $path));
        } catch (MissingViewException $e) {
            if (Configure::read('debug')) {
                throw $e;
            }
            throw new NotFoundException();
        }
    }

    /**
     * Conditions for topics/subtopics that was originally written in the method __getCommonFilterConditions
     *
     * Moved to external method to be used for the reports too
     *
     * @author  Mike <mike@damoiseau.me>
     * @since  2014-01-26
     */
    private function __getCommonFilterTopicConditions( $entity, $entities, &$conditions, &$joins, &$subtopics, &$subTopicId ) {
        if ( isset( $this->params->query['topic_id'] )
            && !empty( $this->params->query['topic_id'] ) ) {
            $topicId = ( int )$this->params->query['topic_id'];

            // if subtopic selected
            $subTopicId = 0;
            if ( isset( $this->params->query['subtopic_id'] )
                && !empty( $this->params->query['subtopic_id'] ) ) {
                $subTopicId = (int) $this->params->query['subtopic_id'];
            }

            $joinConditions = array(
                '`' . $entity . '`.`id` = `IJ_' . $entities . 'Subtopic`.`' . strtolower( $entity ) . '_id`',
            );

            // the subtopic has been selected -> add it to the join's condition
            if( $subTopicId > 0 ) {
                $joinConditions[] = array( 'IJ_' . $entities . 'Subtopic.subtopic_id' => $subTopicId );
            }
            $joins[] = array(
                'alias'         => 'IJ_' . $entities . 'Subtopic',
                'table'         => strtolower( $entities ) . '_subtopics',
                'type'          => 'INNER',
                'conditions'    => $joinConditions,
            );

            // topic selected but not the subtopic
            if( ( $topicId > 0 ) && ( $subTopicId == 0 ) ) {
                $joins[] = array(
                    'alias'         => 'IJ_Subtopic',
                    'table'         => 'subtopics',
                    'type'          => 'INNER',
                    'conditions'    => array(
                        '`IJ_' . $entities . 'Subtopic`.`subtopic_id` = `IJ_Subtopic`.`id`',
                        'IJ_Subtopic.topic_id' => $topicId,
                    ),
                );
            }

            $this->loadModel( 'Subtopic' );
            $subtopics = $this->Subtopic->find( 'list', array(
                'conditions' => array(
                    'Subtopic.topic_id' => $topicId,
                ),
                'order' => array(
                    'Subtopic.name' => 'ASC',
                ),
            ) );
        }
    }

    /**
     * Prepare the conditions array based on the parameters of the filtering
     * @param  array $conditions array of conditions to be applied on the filter query
     * @param  array $joins      array of joins to be applied on the filter query
     *
     * @author  Mike <mike@damoiseau.me>
     * @since  2013-11-26
     * @modified 2013-12-03 - Mike - function receives parameters by reference
     * @modified 2013-12-03 - Mike - Replace the conditions on the subtopics/topics with joins
     * @modified 2013-12-06 - Mike - Added target filter and renamed Joins aliases
     * @modified 2013-12-09 - Mike - Set the subtopics values in controller
     * @modified 2014-01-06 - Mike - Allow use of year only (no month specified)
     * @modified 2014-01-20 - Mike - if one year only, should use a BETWEEN condition!
     * @modified 2014-01-26 - Mike - moved topic/subtopic condition to external private condition so reports will not use __getCommonFilterConditions function anymore
     */
    private function __getCommonFilterConditions( $entity, $entities, &$conditions, &$joins ) {
        // if topic selected
        $subtopics = array();
        $subTopicId = 0;

        $this->__getCommonFilterTopicConditions( $entity, $entities, $conditions, $joins, $subtopics, $subTopicId );

        $this->set( 'subtopic_id', $subTopicId );
        $this->set( 'subtopics', $subtopics );

        // joined date
        // we want to make sure the request is correct:
        // year2 > year OR
        // if year2 == year then month2 >= month
        // Otherwise the end date is before the start date, which is wrong
        $bSkipDateFilter = false;
        if ( isset( $this->params->query['filter_since_year'] ) &&
                !empty( $this->params->query['filter_since_year'] ) ) {

            $year = ( int )$this->params->query['filter_since_year'];
            $year -= 543; // Gregorian calendar

            $month = 1;
            if( isset( $this->params->query['filter_since_month'] ) &&
                    !empty( $this->params->query['filter_since_month'] ) ) {
                $month = ( int )$this->params->query['filter_since_month'];
            }

            $date1 = sprintf( '%d-%d-1', $year, $month );

            if ( isset( $this->params->query['filter_until_year'] ) &&
                    !empty( $this->params->query['filter_until_year'] ) ) {

                $year2 = ( int )$this->params->query['filter_until_year'];
                $year2 -= 543; // Gregorian calendar

                $month2 = 12;
                if( isset( $this->params->query['filter_until_month'] ) &&
                    !empty( $this->params->query['filter_until_month'] ) ) {
                    $month2 = ( int )$this->params->query['filter_until_month'];
                }

                $bSkipDateFilter = ( $year2 < $year ) ||
                                    ( ( $year2 == $year) && ( $month2 < $month ) );

                $date2 = sprintf( '%d-%d-%d', $year2, $month2, cal_days_in_month( CAL_GREGORIAN, $month2, $year2 ) );

                if( !$bSkipDateFilter ) {
                    $conditions[] = CakeTime::daysAsSql( $date1, $date2, $entity . '.joined' );
                }
            } else {
                // $date2 = sprintf( '%d-%d-%d', $year, $month, cal_days_in_month( CAL_GREGORIAN, $month, $year ) );
                $conditions[] = array( $entity . '.joined >= ' => $date1 );
            }

        }

        // target
        if ( isset( $this->params->query['target_id'] ) &&
            !empty( $this->params->query['target_id'] ) ) {
            $targetId = ( int )$this->params->query['target_id'];

            $joins[] = array(
                'alias'         => 'IJ_' . $entities . 'Target',
                'table'         => strtolower( $entities ) . '_targets',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_' . $entities . 'Target`.`' . strtolower ( $entity ) . '_id` = `' . $entity . '`.`id`',
                    'IJ_' . $entities . 'Target.target_id' => $targetId,
                ),
            );
        }
    }

    /**
     * Prepare the array of slugs for Region/Province/District, or any other entity that has the three following fields"
     * - id
     * - name
     * - slug
     * - coords
     * @param  Model $model Model that will be used to get the values from the database
     * @return array        array of values (key is ID and values are {id, name, slug})
     *
     * @author  Mike <mike@damoiseau.me>
     * @since 2013-12-08
     */
    private function __prepareSlugs( &$model, $conditions = array() ) {
        $slugs = array();

        $fields = array(
            $model->alias . '.id',
            $model->alias . '.name',
        );

        $model->schema();
        if ( isset( $model->_schema['slug'] ) ) {
            $fields[] = $model->alias . '.slug';
        }
        if ( isset( $model->_schema['coords'] ) ) {
            $fields[] = $model->alias . '.coords';
        }

        if ( isset( $model->_schema['region_id'] ) ) {
            $fields[] = $model->alias . '.region_id';
        }

        $tmpValues = $model->find( 'all', array(
            'recursive'     => -1,
            'fields'        => $fields,
            'conditions'    => $conditions,
        ) );

        foreach( $tmpValues as &$tmpValue ) {
            $slugs[$tmpValue[$model->alias]['id']] = $tmpValue[$model->alias];
        }
        return $slugs;
    }

    /**
     * Set the colors for each entity on the map
     * @param  int $values the number of organizations for each Region/Province/District
     *
     * @author  Mike <mike@damoiseau.me>
     * @since 2013-12-08
     *
     * @modified - Mike - 2014-05-01 - Get the map range from the Configure class
     */
    private function __prepareColors( &$valuesColors ) {
        $mapColors = Configure::read( 'MAP_COLORS' );
        $nMapColors = count( $mapColors );
        $mapRange = Configure::read( 'MAP_RANGE' );

        // What are the Min and the Max results?
        $v = array_values( $valuesColors );
        $min = min( $v );
        $max = max( $v );
        unset( $v );

        $step = 1.0 * ($max - $min) / $nMapColors;

        foreach( $valuesColors as $kValueColor => $vValueColor ) {
            // for( $i = 0; $i < $nMapColors; $i++ ) {
            //     if( $vValueColor <= ( $min + ( ( $i + 1 ) * $step ) ) ) {
            //         $valuesColors[$kValueColor] = array( $vValueColor, $mapColors[$i] );
            //         break;
            //     }
            // }
            $nEntities = $vValueColor;
            // $nEntities = rand(0, 100);

            if( $nEntities > 0 ) {
                // $nEntities += 10 - 1;
                $nEntities -= 1;
            }
            $nEntities = floor( $nEntities / $mapRange );
            if ( $nEntities >= $nMapColors ) {
                $nEntities = $nMapColors - 1;
            }

            $valuesColors[$kValueColor] = array( $vValueColor, $mapColors[$nEntities] );
        }
    }

    /**
     * Counts the number of distinct organizations found
     * Because of the INNER JOINS that we use for the working areas, we may have duplicated organizations (if more than one working area)
     *
     * @param  array $organizations search results
     * @return int                number of distinct organizations
     *
     * @author  Mike <mike@damoiseau.me>
     * @since 2013-12-08
     */
    private function __countEntities( $modelName, &$entities ) {
        $distincts = array();

        foreach( $entities as $entity ) {
            $distincts[$entity[$modelName]['id']] = $entity[$modelName]['id'];
        }

        return count( $distincts );
    }

    private function __getAllEntitiesInCountry( $entity, $entities ) {
        $this->loadModel( $entity );
        $this->{$entity}->recursive = -1;

        // filtering conditions
        $conditions = array();
        $joins = array();
        $fields = array( $entity . '.id', $entity . '.district_id', $entity . '.joined' );

        $this->__getCommonFilterConditions( $entity, $entities, $conditions, $joins, $fields );

        // Should we use the condition on `district_id` or with the table `districts_organizations` ?
        // 0 = location --> use `district_id`
        // 1 = work area --> use the table `districts_organizations`
        $filterLocationType = 0;
        if ( isset( $this->params->query['filter_location_type'] )
            && !empty( $this->params->query['filter_location_type'] ) ) {
                $filterLocationType = ( int )$this->params->query['filter_location_type'];
        }
        // work on district_id
        if ( $filterLocationType == 0 ) {
            // let's make our own join
            $this->{$entity}->unBindModel( array( 'belongsTo' => array( 'District' ) ) );

            $joins[] = array(
                'alias'         => 'IJ_District',
                'table'         => 'districts',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_District`.`id` = `' . $entity . '`.`district_id`',
                ),
            );
        } else {
            $joins[] = array(
                'alias'         => 'Districts' . $entity,
                'table'         => 'districts_' . strtolower( $entities ),
                'type'          => 'INNER',
                'conditions'    => array(
                    '`' . $entity . '`.`id` = `Districts' . $entity . '`.`' . strtolower( $entity ) . '_id`',
                ),
            );

            $joins[] = array(
                'alias'         => 'IJ_District',
                'table'         => 'districts',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_District`.`id` = `Districts' . $entity . '`.`district_id`',
                ),
            );

            $fields[] = 'Districts' . $entity . '.district_id';
        }
        // make the join with the province in both cases
        $joins[] = array(
            'alias'         => 'IJ_Province',
            'table'         => 'provinces',
            'type'          => 'INNER',
            'conditions'    => array(
                '`IJ_Province`.`id` = `IJ_District`.`province_id`',
            ),
        );

        // if we filter by work area, the map will have to use the field `district_id` that comes from the table `districts_organizations`
        $fields[] = 'IJ_Province.id';
        $fields[] = 'IJ_Province.region_id';

        // 2013-11-12 - Mike - get all the results because we need to set the colors on the map and we cannot work with paginated data for this
        $allEntities = $this->{$entity}->find( 'all', array(
            'fields'        => $fields,
            'conditions'    => $conditions,
            'joins'         => $joins,
            'group' => $entity . '.id'
        ) );

        return $allEntities;
    }

    private function __prepareEntitiesDataForCountry( $entity, $entities, $prepareColors = true ) {
        $allEntities = $this->__getAllEntitiesInCountry( $entity, $entities );

        $this->set( 'number_of_' . strtolower( $entities ), $this->__countEntities( $entity, $allEntities ) );

        // get all the regions for their slug that will be added to the links on the map
        $slugs = $this->__prepareSlugs( $this->{$entity}->District->Province->Region );
        $this->set( 'regions', $slugs );

        // get all the provinces for their slug that will be added to the links on the map
        $slugs = $this->__prepareSlugs( $this->{$entity}->District->Province );
        $this->set( 'provinces_slugs', $slugs );

        // count the number of organizations per province
        // first, initialize all the provinces to 0
        $provincesColors = array();
        $kProvinces = array_keys( $slugs );
        foreach( $kProvinces as &$kProvince ) {
            $provincesColors[$kProvince] = 0;
        }
        foreach( $allEntities as $oneEntity ) {
            $provincesColors[$oneEntity['IJ_Province']['id']]++;
        }
        if ($prepareColors) {
            $this->__prepareColors( $provincesColors );
            $this->set( 'provinces_colors', $provincesColors );
        }

        // compute the colors for the map
        $regionsColors = array( '1' => 0, '2' => 0, '3' => 0, '4' => 0, '5' => 0, '6' => 0,  );

        // count number of org/ppl in each province to use with data table
        // (on the right column)
        $entitiesForTable = array();
        foreach( $allEntities as $org ) {
            if (isset($entitiesForTable[$org['IJ_Province']['id']])) {
                $entitiesForTable[$org['IJ_Province']['id']] += 1;
            } else {
                $entitiesForTable[$org['IJ_Province']['id']] = 1;
            }
            $regionsColors[$org['IJ_Province']['region_id']]++;
        }

        // calling secondary entity will not update map's color
        if ($prepareColors) {
            $this->__prepareColors( $regionsColors );
            $this->set( 'regions_colors', $regionsColors );
        }

        $listRegions = $this->{$entity}->District->Province->Region->find( 'list' );
        $this->set( 'list_regions', $listRegions );

        $this->set('topicTitle', __('หน้าแรก'));
        $this->_setListValues(array('Topic'));

        $this->loadModel( 'Province' );
        $provinces = $this->Province->find( 'all', array(
            'recursive'     => -1,
            'contain'       => array(
                'Region'
            ),
        ) );

        // fill number 0 for provinces that dont have any entities
        foreach ($provinces as $province) {
            if (isset($entitiesForTable[$province['Province']['id']])) {
                $total = $entitiesForTable[$province['Province']['id']];
            } else {
                $total = 0;
            }
            $entitiesForTable[$province['Province']['id']] = array(
                'name' => $province['Province']['name'],
                'total' => $total
            );
        }

        // sort provinces by name
        sort($entitiesForTable);

        $this->set(strtolower($entities) . '_for_table', $entitiesForTable);
        $this->set( 'provinces', $provinces );
    }

    private function __setTargetsInView() {
        $this->_setListValues( array( 'Target' ), 'Target.name' );
    }

    /**
     * front-end home page
     *
     * @author Ting <3Musketeersteam@gmail.com>
     * @since 5 November 2013
     */
    public function index() {
        $this->__prepareEntitiesDataForCountry( 'Organization', 'Organizations' );
        $this->__prepareEntitiesDataForCountry( 'Person', 'People', false );

        // count the people for the table on the right side
        $allEntities = $this->__getAllEntitiesInCountry( 'Person', 'People' );

        //Get all region
        //@todo : accually we can use
        //          $restTotal = array(1 => 'null', 2 => 'null', 3 => 'null', 4 => 'null', 5 => 'null', 6 => 'null');
        //        instead of find data in region table.
        $this->loadModel('Region');
        $this->Region->recursive = -1;
        $restTotal = $this->Region->find('all');
        $restTotal = Hash::combine($restTotal, '{n}.Region.id');
        //Count entities.
        foreach( $restTotal as $kRestTotal => $vRestTotal ) {
           $restTotal[ $kRestTotal ] = 0;
        }

        $this->__countAnotherOrg( $restTotal, $allEntities, 'Province', 'region_' );

        $this->loadModel('Types');
        $listBanner = $this->Types->find( 'all', array( 'conditions' => array( 'Types.type_id' => 1, 'Types.upload_photos !=' => null ) ) );
      
        $this->set('rest_total', $restTotal);
        $this->set('all_entities', $allEntities);
        $this->set('banner', $listBanner);
        $this->set( 'number_of_people', $this->__countEntities( 'Person', $allEntities ) );

        $this->__setTargetsInView();
    }

    public function peopleMapThailand() {
        $this->__prepareEntitiesDataForCountry( 'Organization', 'Organizations' , false);
        $this->__prepareEntitiesDataForCountry( 'Person', 'People' );

        // count the organizations for the table on the right side
        $allEntities = $this->__getAllEntitiesInCountry( 'Organization', 'Organizations' );

        $this->loadModel('Region');
        $this->Region->recursive = -1;
        $restTotal = $this->Region->find('all');
        $restTotal = Hash::combine($restTotal, '{n}.Region.id');

        foreach( $restTotal as $kRestTotal => $vRestTotal ) {
           $restTotal[ $kRestTotal ] = 0;
        }
        //Count entities.
        $this->__countAnotherOrg( $restTotal, $allEntities, 'Province', 'region_' );

        $this->set('rest_total', $restTotal);
        $this->set( 'number_of_organizations', $this->__countEntities( 'Organization', $allEntities ) );

        $this->__setTargetsInView();
    }

    private function __prepareEntitiesDataForRegion( $entity, $entities, $slug ) {
        $this->loadModel( $entity );
        $this->{$entity}->recursive = -1;

        // find the region
        $this->{$entity}->District->Province->Region->recursive = -1;
        $region = $this->{$entity}->District->Province->Region->findBySlug( $slug );
        if( empty( $region ) ) {
            throw new NotFoundException();
        }
        $this->set( 'region', $region );

        $allEntities = $this->__getAllEntitiesInRegion( $entity, $entities, $region );
        $this->set( 'number_of_' . strtolower( $entities ), $this->__countEntities( $entity, $allEntities ) );

        $listProvinces = $this->{$entity}->District->Province->find( 'list', array( 'conditions' => array( 'Province.region_id' => $region['Region']['id'] ) ) );
        $this->set( 'list_provinces', $listProvinces );

        $provinces = $this->__prepareSlugs( $this->{$entity}->District->Province );
        $this->set( 'provinces', $provinces );

        // count the number of organizations per province
        // first, initialize all the provinces to 0
        $provincesColors = array();
        $kProvinces = array_keys( $listProvinces );
        foreach( $kProvinces as &$kProvince ) {
            $provincesColors[$kProvince] = 0;
        }
        foreach( $allEntities as $oneEntity ) {
            $provincesColors[$oneEntity['IJ_Province']['id']]++;
        }

        $this->__prepareColors( $provincesColors );
        $this->set( 'provinces_colors', $provincesColors );

        // the provinces from the other regions should be grayed on the map
        $provincesGray = $this->{$entity}->District->Province->find( 'list', array(
            'conditions' => array(
                'NOT'   => array( 'Province.region_id' => $region['Region']['id'] ),
            )
        ) );
        $this->set( 'provinces_gray', $provincesGray );
        $this->set( 'color_gray', 'EDEDED' );

        $this->_setListValues(array('Topic'));
        $this->set( 'topicTitle', __( $region['Region']['name'] ) );
    }

    /**
     * Display the map of a region
     *
     * @author  Mike <michael.damoiseau@gmail.com>
     * @since  2013-11-13
     *
     * @see  http://stackoverflow.com/questions/12842683/adding-conditions-to-containable-in-cakephp
     */
    public function regions( $slug ) {        
        $this->__prepareEntitiesDataForRegion( 'Organization', 'Organizations', $slug );

        // count the people for the table on the right side
        $this->loadModel( 'Person' );
        $region = $this->Person->District->Province->Region->findBySlug( $slug );
        $allEntities = $this->__getAllEntitiesInRegion( 'Person', 'People', $region );

        //Get all province of this region.
        $this->loadModel('Province');
        $this->Province->recursive = -1;

        $restTotal = $this->Province->find( 'list', array(
           'conditions' => array( 'Province.region_id' => $region['Region']['id'] )
        ));

        foreach( $restTotal as $kRestTotal => $vRestTotal ) {
           $restTotal[ $kRestTotal ] = 0;
        }

        //Count entities.
        $this->__countAnotherOrg( $restTotal, $allEntities, 'Province' );

        $this->set('rest_total', $restTotal);
        $this->set( 'number_of_people', $this->__countEntities( 'Person', $allEntities ) );

        $this->__setTargetsInView();
    }

    public function peopleMapRegions( $slug ) {
        $this->__prepareEntitiesDataForRegion( 'Person', 'People', $slug );

        // count the organizations for the table on the right side
        $this->loadModel( 'Organization' );
        $region = $this->Organization->District->Province->Region->findBySlug( $slug );
        $allEntities = $this->__getAllEntitiesInRegion( 'Organization', 'Organizations', $region );

        //Get all province of this region.
        $this->loadModel('Province');
        $this->Province->recursive = -1;

        $restTotal = $this->Province->find( 'list', array(
           'conditions' => array( 'Province.region_id' => $region['Region']['id'] )
        ));

        foreach( $restTotal as $kRestTotal => $vRestTotal ) {
           $restTotal[ $kRestTotal ] = 0;
        }

        //Count entities.
        $this->__countAnotherOrg( $restTotal, $allEntities, 'Province' );

        $this->set('rest_total', $restTotal);
        $this->set( 'number_of_organizations', $this->__countEntities( 'Organization', $allEntities ) );

        $this->__setTargetsInView();
    }

    private function __getAllEntitiesInRegion( $entity, $entities, $region ) {
        // filtering conditions
        $conditions = array();
        $joins = array();
        $fields = array( $entity . '.id', $entity . '.district_id', $entity . '.joined' );
        $this->__getCommonFilterConditions( $entity, $entities, $conditions, $joins, $fields );

        // Should we use the condition on `district_id` or with the table `districts_organizations` ?
        // 0 = location --> use `district_id`
        // 1 = work area --> use the table `districts_organizations`
        $filterLocationType = 0;
        if ( isset( $this->params->query['filter_location_type'] )
            && !empty( $this->params->query['filter_location_type'] ) ) {
                $filterLocationType = ( int )$this->params->query['filter_location_type'];
        }
        // work on district_id
        if ( $filterLocationType == 0 ) {
            // let's make our own join
            $this->{$entity}->unBindModel( array( 'belongsTo' => array( 'District' ) ) );

            $joins[] = array(
                'alias'         => 'IJ_District',
                'table'         => 'districts',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_District`.`id` = `' . $entity . '`.`district_id`',
                ),
            );
        } else {
            $joins[] = array(
                'alias'         => 'Districts' . $entity,
                'table'         => 'districts_' . strtolower( $entities ),
                'type'          => 'INNER',
                'conditions'    => array(
                    '`' . $entity . '`.`id` = `Districts' . $entity . '`.`' . strtolower( $entity ) . '_id`',
                ),
            );

            $joins[] = array(
                'alias'         => 'IJ_District',
                'table'         => 'districts',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_District`.`id` = `Districts' . $entity . '`.`district_id`',
                ),
            );

            $fields[] = 'Districts' . $entity . '.district_id';
        }
        // make the join with the province in both cases
        $joins[] = array(
            'alias'         => 'IJ_Province',
            'table'         => 'provinces',
            'type'          => 'INNER',
            'conditions'    => array(
                '`IJ_Province`.`id` = `IJ_District`.`province_id`',
                // we only need the orgs with working area in the selected region
                'IJ_Province.region_id' => $region['Region']['id'],
            ),
        );

        // if we filter by work area, the map will have to use the field `district_id` that comes from the table `districts_organizations`
        $fields[] = 'IJ_Province.id';
        $fields[] = 'IJ_Province.region_id';

        $allEntities = $this->{$entity}->find( 'all', array(
            'recursive'     => -1,
            'fields'        => $fields,
            'conditions'    => $conditions,
            'joins'         => $joins,
        ) );

        return $allEntities;
    }

    private function __getAllEntitiesInProvince( $entity, $entities, $province) {
        // filtering conditions
        $conditions = array();
        $joins = array();
        $fields = array( $entity . '.id', $entity . '.district_id', $entity . '.joined' );
        $this->__getCommonFilterConditions( $entity, $entities, $conditions, $joins, $fields );

        $filterLocationType = 0;
        if ( isset( $this->params->query['filter_location_type'] )
            && !empty( $this->params->query['filter_location_type'] ) ) {
                $filterLocationType = ( int )$this->params->query['filter_location_type'];
        }

        // work on district_id
        if ( $filterLocationType == 0 ) {
            // let's make our own join
            $this->{$entity}->unBindModel( array( 'belongsTo' => array( 'District' ) ) );

            $joins[] = array(
                'alias'         => 'IJ_District',
                'table'         => 'districts',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_District`.`id` = `' . $entity . '`.`district_id`',
                    array( 'IJ_District.province_id' => $province['Province']['id'] ),
                ),
            );
        } else {
            $joins[] = array(
                'alias'         => 'Districts' . $entity,
                'table'         => 'districts_' . strtolower( $entities ),
                'type'          => 'INNER',
                'conditions'    => array(
                    '`' . $entity . '`.`id` = `Districts' . $entity . '`.`' . strtolower( $entity ) . '_id`',
                ),
            );

            $joins[] = array(
                'alias'         => 'IJ_District',
                'table'         => 'districts',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_District`.`id` = `Districts' . $entity . '`.`district_id`',
                    array( 'IJ_District.province_id' => $province['Province']['id'] ),
                ),
            );

            $fields[] = 'Districts' . $entity . '.district_id';
        }

        // if we filter by work area, the map will have to use the field `district_id` that comes from the table `districts_organizations`
        $fields[] = 'IJ_District.id';
        $fields[] = 'IJ_District.province_id';

        $allEntities = $this->{$entity}->find( 'all', array(
            'recursive'     => -1,
            'fields'        => $fields,
            'conditions'    => $conditions,
            'joins'         => $joins
        ) );

        return $allEntities;
    }

    private function __prepareEntitiesDataForProvince( $entity, $entities, $slug ) {
        $this->loadModel( $entity );
        $this->{$entity}->recursive = -1;

        $this->{$entity}->District->Province->recursive = -1;
        $province = $this->{$entity}->District->Province->findBySlug( $slug );
        if( empty( $province ) ) {
            throw new NotFoundException();
        }
        $this->set( 'province', $province );

        $allEntities = $this->__getAllEntitiesInProvince( $entity, $entities, $province );
        $this->set( 'number_of_' . strtolower( $entities ), $this->__countEntities( $entity, $allEntities ) );

        $listDistricts = $this->{$entity}->District->find( 'list', array( 'conditions' => array( 'District.province_id' => $province['Province']['id'] ) ) );
        $this->set( 'list_districts', $listDistricts );

        $districts = $this->__prepareSlugs( $this->{$entity}->District, array( 'District.province_id' => $province['Province']['id'] ) );
        $this->set( 'districts', $districts );

        $listProvinces = $this->{$entity}->District->Province->find( 'list', array( 'conditions' => array( 'Province.region_id' => $province['Province']['region_id'] ) ) );
        $this->set( 'list_provinces', $listProvinces );

        $provinces = $this->__prepareSlugs( $this->{$entity}->District->Province, array( 'Province.region_id' => $province['Province']['region_id'] ) );
        $this->set( 'provinces', $provinces );

        // count the number of organizations per province
        // first, initialize all the provinces to 0
        $districtsColors = array();
        $kDistricts = array_keys( $listDistricts );
        foreach( $kDistricts as &$kDistrict ) {
            $districtsColors[$kDistrict] = 0;
        }
        foreach( $allEntities as $oneEntity ) {
            $districtsColors[$oneEntity['IJ_District']['id']]++;
        }

        $this->__prepareColors( $districtsColors );
        $this->set( 'districts_colors', $districtsColors );

        $this->_setListValues( array( 'Topic' ) );
        $this->set( 'topicTitle', __( $province['Province']['name'] ) );
    }

    public function peopleMapProvinces( $slug ) {
        $this->__prepareEntitiesDataForProvince( 'Person', 'People', $slug );

        // count the organizations for the table on the right side
        $this->loadModel( 'Organization' );
        $province = $this->Organization->District->Province->findBySlug( $slug );
        $allEntities = $this->__getAllEntitiesInProvince( 'Organization', 'Organizations', $province );

        //Get all districts of this province.
        $this->loadModel('District');
        $this->District->recursive = -1;

        $restTotal = $this->District->find( 'list', array(
           'conditions' => array( 'District.province_id' => $province['Province']['id'] )
        ));

        foreach( $restTotal as $kRestTotal => $vRestTotal ) {
           $restTotal[ $kRestTotal ] = 0;
        }

        //Count entities.
        $this->__countAnotherOrg( $restTotal, $allEntities, 'District' );

        $this->set('rest_total', $restTotal);
        $this->set( 'number_of_organizations', $this->__countEntities( 'Organization', $allEntities ) );

        $this->__setTargetsInView();
    }

    public function provinces( $slug ) {
        //debug($slug);
        $this->__prepareEntitiesDataForProvince( 'Organization', 'Organizations', $slug );

        // count the people for the table on the right side
        $this->loadModel( 'Person' );
        $province = $this->Person->District->Province->findBySlug( $slug );
        $allEntities = $this->__getAllEntitiesInProvince( 'Person', 'People', $province );

        //Get all districts of this province.
        $this->loadModel('District');
        $this->District->recursive = -1;
        $restTotal = $this->District->findAllByProvinceId($province['Province']['id']);
        $restTotal = $this->District->find( 'list', array(
           'conditions' => array( 'District.province_id' => $province['Province']['id'] )
        ));

        foreach( $restTotal as $kRestTotal => $vRestTotal ) {
           $restTotal[ $kRestTotal ] = 0;
        }

        //Count entities.
        $this->__countAnotherOrg( $restTotal, $allEntities, 'District' );

        $this->set('rest_total', $restTotal);
        $this->set( 'number_of_people', $this->__countEntities( 'Person', $allEntities ) );

        $this->__setTargetsInView();
    }

    /**
     * Count ting amount of entities.
     *
     * @param  array $restTotal
     * @param  array $allEntities
     * @param  string $reference
     * @param  string $field
     * @return array data of entities.
     * @author Ting <3Musketeersteam@gmail.com>
     * @since 3 January 2014
     */
    private function __countAnotherOrg( &$restTotal, $allEntities, $reference, $field = null ) {
       //Counting entities
        for ( $i = 0; $i < count($allEntities); $i++ ) {
            $regionID = $allEntities[$i]['IJ_' . $reference][ $field . 'id'];
            $restTotal[ $regionID ]++;
       }
    }

    public function set_provinces_slugs() {
        $this->loadModel( 'Province' );
        $provinces = $this->Province->find( 'list' );
        foreach( $provinces as $id => $name ) {
            $this->Province->id = $id;
            $this->Province->saveField( 'slug', $name );
        }
    }

    public function error404() {
        $this->set('topicTitle', __('เกิดข้อผิดพลาด'));
    }

    public function admin_error404() {
        $this->layout = 'admin_error';
        $this->set('message', $this->request->params['named']['message']);
    }

    private function __prepareDataForChartCountry( $entity, $entities ) {
        $allEntities = $this->__getAllEntitiesInCountry( $entity, $entities );
        $this->set( strtolower( $entities ), $allEntities );

        $listRegions = $this->{$entity}->District->Province->Region->find( 'list', array(
            'recursive' => -1,
            'order'     => array( 'Region.name' => 'ASC' ),
        ) );
        $this->set( 'list_regions', array_values( $listRegions ) );

        // let's count the number of organizations in each region
        // also, the keys of the array must be in the same order for the labels and for the data, because the char
        // plugin does not use keys or assiative arrays
        $countersRegions = $listRegions;
        // first, initialize each region counter to 0
        foreach( $countersRegions as &$region ) {
            $region = 0;
        }
        // then, let's loop through all our organizations and increment the counter of the region attached to it
        foreach( $allEntities as &$oneEntity ) {
            $countersRegions[$oneEntity['IJ_Province']['region_id']]++;
        }
        // we must use array_values because the chart plugin does not accep associative arrays, only normal arrays
        $this->set( 'counters_regions', array_values( $countersRegions ) );
        $this->set( 'all_entities', $allEntities );

        $this->set('topicTitle', __('แผนภูมิแสดงจำนวนองค์กร'));
        $this->_setListValues(array('Topic'));
    }

    public function chartCountry() {
        $this->__prepareDataForChartCountry( 'Organization', 'Organizations' );

        $this->__setTargetsInView();
    }

    public function chartPeopleCountry() {
        $this->__prepareDataForChartCountry( 'Person', 'People' );

        $this->__setTargetsInView();
    }

    private function __prepareDataForChartRegion( $entity, $entities, $id ) {
        $this->loadModel( $entity );
        $this->{$entity}->recursive = -1;

        // find the region
        $this->{$entity}->District->Province->Region->recursive = -1;
        $region = $this->{$entity}->District->Province->Region->findById( $id );
        if( empty( $region ) ) {
            throw new NotFoundException();
        }
        $this->set( 'region', $region );

        $allEntities = $this->__getAllEntitiesInRegion( $entity, $entities, $region );
        $this->set( $entities, $allEntities );

        // $this->Organization->District->Province->recursive = -1;
        // $provinces = $this->Organization->District->Province->findAllByRegionId($id);
        // $provinces = Hash::extract($provinces, '{n}.Province.name');
        // $this->set('provinces', $provinces);

        $listProvinces = $this->{$entity}->District->Province->find( 'list', array(
            'recursive'     => -1,
            'conditions'    => array(
                'Province.region_id'    => $region['Region']['id'],
            ),
            'order'         => array( 'Province.name' => 'ASC' ),
        ) );
        $this->set( 'list_provinces', array_values( $listProvinces ) );

        // let's count the number of organizations in each region
        // also, the keys of the array must be in the same order for the labels and for the data, because the char
        // plugin does not use keys or assiative arrays
        $countersProvinces = $listProvinces;
        // first, initialize each region counter to 0
        foreach( $countersProvinces as &$province ) {
            $province = 0;
        }
        // then, let's loop through all our organizations and increment the counter of the region attached to it
        foreach( $allEntities as &$oneEntity ) {
            $countersProvinces[$oneEntity['IJ_Province']['id']]++;
        }
        // we must use array_values because the chart plugin does not accep associative arrays, only normal arrays
        $this->set( 'counters_provinces', array_values( $countersProvinces ) );
        $this->set( 'all_entities', $allEntities );

        $this->set('topicTitle', __('แผนภูมิแสดงจำนวนองค์กร ตามภูมิภาค'));
        $this->_setListValues(array('Topic'));
    }

    public function chartRegion( $id ) {
        $this->__prepareDataForChartRegion( 'Organization', 'Organizations', $id );

        $this->__setTargetsInView();
    }

    public function chartPeopleRegion( $id ) {
        $this->__prepareDataForChartRegion( 'Person', 'People', $id );

        $this->__setTargetsInView();
    }

    private function __prepareDataForChartProvince( $entity, $entities, $id ) {
        $this->loadModel( $entity );
        $this->{$entity}->recursive = -1;

        // find the region
        $this->{$entity}->District->Province->recursive = -1;
        $province = $this->{$entity}->District->Province->findById( $id );
        if( empty( $province ) ) {
            throw new NotFoundException();
        }
        $this->set( 'province', $province );

        $allEntities = $this->__getAllEntitiesInProvince( $entity, $entities, $province );
        $this->set( strtolower( $entities ), $allEntities );

        $listDistricts = $this->{$entity}->District->find( 'list', array(
            'recursive'     => -1,
            'conditions'    => array(
                'District.province_id'    => $province['Province']['id'],
            ),
            'order'         => array( 'District.name' => 'ASC' ),
        ) );
        $this->set( 'list_districts', array_values( $listDistricts ) );

        // let's count the number of organizations in each region
        // also, the keys of the array must be in the same order for the labels and for the data, because the char
        // plugin does not use keys or assiative arrays
        $countersDistricts = $listDistricts;
        // first, initialize each region counter to 0
        foreach( $countersDistricts as &$district ) {
            $district = 0;
        }
        // then, let's loop through all our organizations and increment the counter of the region attached to it
        foreach( $allEntities as &$oneEntity ) {
            $countersDistricts[$oneEntity['IJ_District']['id']]++;
        }
        // we must use array_values because the chart plugin does not accep associative arrays, only normal arrays
        $this->set( 'counters_districts', array_values( $countersDistricts ) );
        $this->set( 'all_entities', $allEntities );

        $this->set('topicTitle', __('แผนภูมิแสดงจำนวนองค์กร ตามจังหวัด'));
        $this->_setListValues(array('Topic'));
    }

    public function chartPeopleProvince( $id ) {
        $this->__prepareDataForChartProvince( 'Person', 'People', $id );

        $this->__setTargetsInView();
    }

    public function chartProvince( $id ) {
        $this->__prepareDataForChartProvince( 'Organization', 'Organizations', $id );

        $this->__setTargetsInView();
    }

    /************************
     *       REPORTS        *
     ************************/



    public function reports() {
        $this->redirect( array( 'action' => 'reports_organizations') );
    }

    public function reports_organizations() {
        $this->_setListValues( array( 'Type', 'Topic', 'Member', 'Region' ) );

        $this->__reports_entities( 'Organization', 'Organizations', 'joined' );

        $this->set('topicTitle', __('กราฟสถิติเครือข่าย/กิจกรรม'));
    }

    public function reports_people() {
        $this->_setListValues( array( 'Type', 'Topic', 'Member', 'Region' ) );

        $this->__reports_entities( 'Person', 'People', 'joined' );

        $this->set('topicTitle', __('รายงานเปรียบเทียบ'));
    }

    public function reports_activities() {
        $this->_setListValues( array( 'Type', 'Topic', 'Member', 'Region' ) );

        $this->__reports_entities( 'Activity', 'Activities', 'started' );

        $this->set('topicTitle', __('รายงานเปรียบเทียบ'));
    }

    /**
     * Create the conditions and joins for the reports based on the filters
     *
     * @param  string $entity     Singular name of the entity to search (Organization, Person, Activity)
     * @param  string $entities   Plural name of the entity to search (Organizations, People, Activities)
     * @param  array $conditions array of conditions to use in the `find` method
     * @param  array $joins         array of joins to use in the `find` method
     * @param  boolean $displayAsBusinessYear         use normal year or business year (Oct 1 to Sept 30 of next year)
     * @return  none
     */
    private function __getCommonReportsFiltersConditions( $entity, $entities, &$conditions, &$joins, $fields, $displayAsBusinessYear ) {
        // if topic selected
        $subtopics = array();
        $subTopicId = 0;

        $this->__getCommonFilterTopicConditions( $entity, $entities, $conditions, $joins, $subtopics, $subTopicId );

        $this->set( 'subtopic_id', $subTopicId );
        $this->set( 'subtopics', $subtopics );

        // member id (only for organizations)
        if ( isset( $this->params->query['member_id'] ) && !empty( $this->params->query['member_id'] ) ) {
            $this->loadModel( 'OrgMembership' );
            $idTypes = $this->OrgMembership->find( 'list', array(
                'recursive'     => -1,
                'conditions'    => array(
                    'OrgMembership.member_id'  => ( int )$this->params->query['member_id'],
                ),
                'fields'        => array( 'OrgMembership.member_id', 'OrgMembership.organization_id' ),
                'order'         => array( 'OrgMembership.organization_id' ),
            ) );

            $conditions[$entity . '.id'] = ( array )array_values( $idTypes );
        }

        // type id (only organizations)
        // I am not using an INNER JOIN here because I don't want to receive a new result for each organization <-> type set
        // Instead, I only want all the organizations that are attached to the given type, without any duplicate
        if ( isset( $this->params->query['type_id'] ) && !empty( $this->params->query['type_id'] ) ) {
            $this->loadModel( $entities . 'Type' );
            $idTypes = $this->{$entities . 'Type'}->find( 'list', array(
                'recursive'     => -1,
                'conditions'    => array(
                    $entities . 'Type.type_id'  => ( int )$this->params->query['type_id'],
                ),
                'fields'        => array( $entities . 'Type.type_id', 'OrganizationsType.organization_id' ),
                'order'         => array( $entities . '.organization_id' ),
            ) );

            if( isset( $conditions[$entity . '.id'] ) ) {
                $conditions[$entity . '.id'] = array_merge( $conditions[$entity . '.id'], array_values( $idTypes ) );
            } else {
                $conditions[$entity . '.id'] = array_values( $idTypes );
            }
        }

        // years stuff
        // Here is the logic for *one year only* :
        // - if normal year: start date is `January 1, $year1` and end date is `December 31, $year1`
        // - if business year: start date is `October 1, $year1` and end date is `September 30, ($year1 + 1)`
        // Same logic applies for two years given, except that the end date for business year is `September 30, ($year2 + 1)`
/*
         if ( isset( $this->params->query['filter_since_year'] ) &&
                !empty( $this->params->query['filter_since_year'] ) ) {

            $year = ( int )$this->params->query['filter_since_year'];
            $year -= 543; // Gregorian calendar

            if( $displayAsBusinessYear ) {
                $month = 10;
            } else {
                $month = 1;
            }
            $date1 = sprintf( '%d-%d-1', $year, $month );

            if ( isset( $this->params->query['filter_until_year'] ) &&
                    !empty( $this->params->query['filter_until_year'] ) ) {

                $year2 = ( int )$this->params->query['filter_until_year'];
                $year2 -= 543; // Gregorian calendar
            } else {
                $year2 = $year;
            }

            if( $displayAsBusinessYear ) {
                $month2 = 9;
                $year2 += 1;
            } else {
                $month2 = 12;
            }

            $bSkipDateFilter = ( $year2 < $year ) ||
                                ( ( $year2 == $year) && ( $month2 < $month ) );

            $date2 = sprintf( '%d-%d-%d', $year2, $month2, cal_days_in_month( CAL_GREGORIAN, $month2, $year2 ) );
            if( !$bSkipDateFilter ) {
                $conditions[] = CakeTime::daysAsSql( $date1, $date2, $entity . '.joined' );
            } else {
                    $date2 = sprintf( '%d-12-31', $year );
                    $conditions[] = CakeTime::daysAsSql( $date1, $date2, $entity . '.joined' );
            }
        }
*/

    }

    /**
     * Create the reports one type of entity
     *
     * @param  string $entity Singular name of the entity (Organization, Person, Activity)
     * @param  string $entities Plural name of the entitiy (Organizations, People, Activities)
     * @param  string $dateField    Name of the field to use for the date (`joined` or `created` for activity)
     * @return [type]           [description]
     */
    private function __reports_entities( $entity, $entities, $dateField ) {
        $conditions = array();
        $joins = array();
        $fields = array( $entity . '.id', $entity . '.district_id', $entity . '.' . $dateField );

        /**
         * Are we displaying the data in a normal year or in a business year?
         * - a normal year starts Jan 01 and ends Dec 31
         * - a business year starts Oct 01 and ends Sept 30 of next year
         */
        $displayAsBusinessYear = isset( $this->params->query['year_type'] ) && ( ( int )$this->params->query['year_type'] == 1 );

        $this->__getCommonReportsFiltersConditions( $entity, $entities, $conditions, $joins, $fields, $displayAsBusinessYear );

        $this->loadModel( $entity );

        // locations
        $joinsLocation = array(
            array(
                'alias'         => 'IJ_District',
                'table'         => 'districts',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_District`.`id` = `' . $entity . '`.`district_id`',
                ),
            ),
            array(
                'alias'         => 'IJ_Province',
                'table'         => 'provinces',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_Province`.`id` = `IJ_District`.`province_id`',
                ),
            ),
            array(
                'alias'         => 'IJ_Region',
                'table'         => 'regions',
                'type'          => 'INNER',
                'conditions'    => array(
                    '`IJ_Region`.`id` = `IJ_Province`.`region_id`',
                ),
            ),
        );

        /**
         * Do we display a vertical or horizontal chart (country and 1 district display vertical, region and province display horizontal)
         * Also, prepare the X axis data (which becomes Y axis on horizontal graphs but weirdly enough, keeps the name X axis) if no year selected
         */
        $displayVerticalGraph = true;
        $areaLevel = '';
        if ( isset( $this->params->query['district_id'] ) && !empty( $this->params->query['district_id'] ) ) {
            $joinsLocation[0]['conditions']['IJ_District.id'] = ( int )$this->params->query['district_id'];
            $areaLevel = 'IJ_District';

            $areas = $this->{$entity}->District->find( 'list', array(
                'conditions' => array(
                    'District.id' => $joinsLocation[0]['conditions']['IJ_District.id']
                )
            ) );
        } else if ( isset( $this->params->query['province_id'] ) && !empty( $this->params->query['province_id'] ) ) {
            $joinsLocation[1]['conditions']['IJ_Province.id'] = ( int )$this->params->query['province_id'];
            $areaLevel = 'IJ_District';

            $displayVerticalGraph = false;

            $areas = $this->{$entity}->District->find( 'list', array(
                'conditions'    => array(
                    'District.province_id' => $joinsLocation[1]['conditions']['IJ_Province.id']
                ),
                'order'         => array( 'District.name' ),
            ) );
        } else if ( isset( $this->params->query['region_id'] ) && !empty( $this->params->query['region_id'] ) ) {
            $joinsLocation[2]['conditions']['IJ_Region.id'] = ( int )$this->params->query['region_id'];
            $areaLevel = 'IJ_Province';

            $displayVerticalGraph = false;

            $areas = $this->{$entity}->District->Province->find( 'list', array(
                'conditions'    => array(
                    'Province.region_id' => $joinsLocation[2]['conditions']['IJ_Region.id']
                ),
                'order'         => array( 'Province.name' ),
            ) );
        } else {
            $areaLevel = 'IJ_Region';

            $areas = $this->{$entity}->District->Province->Region->find( 'list', array(
                'order'         => array( 'Region.name' ),
            ) );
        }

        $joins = array_merge( $joins, $joinsLocation );

        // find the entities
        $allEntities = $this->{$entity}->find( 'all', array(
            'recursive'     => -1,
            'fields'        => array_merge( $fields, array( 'IJ_District.id', 'IJ_Province.id', 'IJ_Region.id' ) ),
            'conditions'    => $conditions,
            'joins'         => $joins,
        ) );

        // Do we use the `increased` parameter?
        $bIncreasedResults =  !empty( $this->params->query['results_type'] ) && ( $this->params->query['results_type'] == '1' );

        $this->set( 'number_of_' . strtolower( $entities ), $this->__countEntities( $entity, $allEntities ) );

        // no filter on years, use the areas as X axis
        if( empty( $this->request->query['filter_since_year'] ) ) {
            $x_axis = array_values( $areas );

            $y_axis = $areas;
            foreach( $y_axis as $kY_axis => $vY_axis ) {
                $y_axis[$kY_axis] = 0;
            }

            foreach( $allEntities as $oneEntity ) {
                $y_axis[ $oneEntity[$areaLevel]['id'] ]++;
            }
            $y_axis = array_values( $y_axis );
        } else {
            // only 1 year given, use the twelve months then
            if( empty( $this->request->query['filter_until_year'] ) ) {
                $x_axis = array_values( Configure::read( 'MONTHS' ) );

                $y_axis = array();
                $y_axis = array_fill(0, 12, 0);

                $old_y_axis = array();
                $old_y_axis = array_fill(0, 12, 0);

                $filterYear = ( int )$this->request->query['filter_since_year'];
                $filterYear -= 543;

                foreach( $allEntities as $oneEntity ) {
                    $month = explode( '-', $oneEntity[$entity][$dateField] );
                    $year = ( int )$month[0];
                    $month = ( int )$month[1];

                    // do we display business years?
                    if( $displayAsBusinessYear && ($month < 10 ) ) {
                        $year--;
                    }

                    if( $year < $filterYear ) {
                        $old_y_axis[ $month - 1 ]++;
                    } else if( $year == $filterYear ) {
                        $y_axis[ $month - 1 ]++;
                    }
                }

                if( !$bIncreasedResults ) {
                    for( $i = 0; $i < 12; $i++ ) {
                        $y_axis[$i] += $old_y_axis[$i];
                    }
                }

                // Now we only need to reorder the arrays if we are in a business year
                // In that case, we take the last three elements of the array and move them to the beginning of the array
                if( $displayAsBusinessYear ) {
                    // reorder the months
                    for( $i = 0; $i < 3; $i++ ) {
                        // remove month from the end of the array
                        $elt = array_pop( $x_axis );
                        // add the month to the beginning of the array
                        array_unshift( $x_axis, $elt );

                        // remove month from the end of the array
                        $elt = array_pop( $y_axis );
                        // add the month to the beginning of the array
                        array_unshift( $y_axis, $elt );
                    }
                } // $displayAsBusinessYear

            } else {
                // 2 years given, use the years on the Y axis
                $year_start = ( int )$this->request->query['filter_since_year'];
                $year_end = ( int )$this->request->query['filter_until_year'];

                $filterYear = $year_start - 543;
                $filterYearEnd = $year_end - 543;

                $x_axis = array();
                $y_axis = array();
                $beforeYear = 0;

                for( $i = $year_start; $i <= $year_end; $i++ ) {
                    $x_axis[] = $i;
                    $y_axis[] = 0;
                }
                // @todo Do not forget the business year parameter here!!!

                foreach( $allEntities as $oneEntity ) {
                    $year = explode( '-', $oneEntity[$entity][$dateField] );
                    $month = $year[1];
                    $year = $year[0];

                    // do we display business years?
                    if( $displayAsBusinessYear && ($month < 10 ) ) {
                        $year--;
                    }

                    // if before the start year, add it to the `before year` counter (used for normal years display intialization)
                    if( $year < $filterYear ) {
                        $beforeYear++;
                        // we are in the range of `start year` and `end year`
                    } else if( $year <= $filterYearEnd ) {
                        $y_axis[ $year - $year_start + 543 ]++;
                    }
                    // there is no `else`, it would mean the org that joined *after* the end year filter
                }



                if( !$bIncreasedResults ) {
                    $max = count( $y_axis ) - 1;
                    for( $i = $max; $i >= 0; $i-- ) {
                        for( $j = 0; $j < $i; $j++ ) {
                            $y_axis[$i] += $y_axis[$j];
                        }
                        $y_axis[$i] += $beforeYear;
                    }
                }

            }
        }

        $this->set( 'x_axis', $x_axis );
        $this->set( 'y_axis', $y_axis );
        $this->set( 'display_vertical_graph', $displayVerticalGraph );

        // region, province, district
        $regionId = 0;
        $provinceId = 0;
        $districtId = 0;

        $provinces = array();
        $districts = array();
        if ( isset($this->params->query['region_id'])
            && !empty($this->params->query['region_id']) ) {
            $regionId = (int)$this->params->query['region_id'];

            // set list values for province_id field in the view
            $this->loadModel('Province');
            $provinces = $this->Province->find('list',
                array(
                    'conditions' => array('region_id' => $regionId)
                ));

            // select region and province
            if ( isset($this->params->query['province_id'])
                && !empty($this->params->query['province_id']) ) {
                $provinceId = (int)$this->params->query['province_id'];

                $districts = $this->{$entity}->District->find('list',
                    array(
                        'conditions' => array('District.province_id' => $provinceId)
                ));

                // specific district
                if ( isset($this->params->query['district_id'])
                    && !empty($this->params->query['district_id']) ) {
                    $districtId = (int)$this->params->query['district_id'];
                    $conditions['AND']['Organization.district_id'] = $districtId;
                }
            }
        }
        $this->set('region_id', $regionId);
        $this->set('province_id', $provinceId);
        $this->set('district_id', $districtId);

        $this->set('provinces', $provinces);
        $this->set('districts', $districts);
    }

    /**
     * This is the report 3.2
     */
    public function allinfo_reports_organizations() {
        $this->_setListValues( array( 'Type', 'Topic', 'Member', 'Region' ) );

        $this->__allinfo_reports_entities( 'Organization', 'Organizations', 'joined' );

        $this->set('topicTitle', __('ตารางจำนวนเครือข่ายหรือ กิจกรรมตามเงือนไขที่ระบุ'));

        if (isset($this->params->ext)) {
            if ($this->params->ext == 'pdf') {
                $this->_renderPdf(array(), '/Pages/pdf/allinfo_reports_organizations');
            } else if ($this->params->ext == 'csv') {
                $this->render('/Elements/csv/allinfo_organizations', false);
            }
        }
    }

    public function allinfo_reports_people() {
        $this->_setListValues( array( 'Type', 'Topic', 'Member', 'Region' ) );

        $this->__allinfo_reports_entities( 'Person', 'People', 'joined' );

        $this->set('topicTitle', __('รายงานเปรียบเทียบ'));

        if (isset($this->params->ext)) {
            if ($this->params->ext == 'pdf') {
                $this->_renderPdf(array(), '/Pages/pdf/allinfo_reports_organizations');
            } else if ($this->params->ext == 'csv') {
                $this->render('/Elements/csv/allinfo_organizations', false);
            }
        }
    }

    public function allinfo_reports_activities() {
        $this->_setListValues( array( 'Type', 'Topic', 'Member', 'Region' ) );

        $this->__allinfo_reports_entities( 'Activity', 'Activities', 'started' );

        $this->set('topicTitle', __('รายงานเปรียบเทียบ'));

        if (isset($this->params->ext)) {
            if ($this->params->ext == 'pdf') {
                $this->_renderPdf(array(), '/Pages/pdf/allinfo_reports_organizations');
            } else if ($this->params->ext == 'csv') {
                $this->render('/Elements/csv/allinfo_organizations', false);
            }
        }
    }

    /**
     * create the All Info reports for givent entity (reports 3.2 request)
     *
     * @param  string $entity    singular name of the entity
     * @param  string $entities  plural name of the entity
     * @param  string $dateField name of the field to use (`joined` or something else)
     *
     * @author Mike <mike@damoiseau.me>
     * @since  2014-01-30
     */
    private function __allinfo_reports_entities( $entity, $entities, $dateField ) {
        $conditions = array();
        $joins = array();
        $fields = array( $entity . '.id', $entity . '.' . $dateField );

        $displayBy = !empty( $this->request->query['filter_display_by'] ) ? $this->request->query['filter_display_by'] : 'topics';

        switch( $displayBy ) {
            case 'months':
                break;

            case 'years':
                break;

            case 'regions':
                $fields[] = 'IJ_Region.id' ;

                $model = 'Region';

                $joins = array(
                    array(
                        'alias'         => 'IJ_District',
                        'table'         => 'districts',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_District`.`id` = `' . $entity . '`.`district_id`',
                        ),
                    ),
                    array(
                        'alias'         => 'IJ_Province',
                        'table'         => 'provinces',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_Province`.`id` = `IJ_District`.`province_id`',
                        ),
                    ),
                    array(
                        'alias'         => 'IJ_Region',
                        'table'         => 'regions',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_Region`.`id` = `IJ_Province`.`region_id`',
                        ),
                    ),
                );

                break;

            case 'provinces':
                $fields[] = 'IJ_Province.id';

                $model = 'Province';

                $joins = array(
                    array(
                        'alias'         => 'IJ_District',
                        'table'         => 'districts',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_District`.`id` = `' . $entity . '`.`district_id`',
                        ),
                    ),
                    array(
                        'alias'         => 'IJ_Province',
                        'table'         => 'provinces',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_Province`.`id` = `IJ_District`.`province_id`',
                        ),
                    ),
                );

                break;

            case 'subtopics':
                $fields[] = 'IJ_Subtopic.id';

                $model = 'Subtopic';

                $joins = array(
                    array(
                        'alias'         => 'IJ_' . $entities . 'Subtopic',
                        'table'         => strtolower( $entities ) . '_subtopics',
                        'type'          => 'INNER',
                        'conditions'    => '`' . $entity . '`.`id` = `IJ_' . $entities . 'Subtopic`.`' . strtolower( $entity ) . '_id`',
                    ),
                    array(
                        'alias'         => 'IJ_Subtopic',
                        'table'         => 'subtopics',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_' . $entities . 'Subtopic`.`subtopic_id` = `IJ_Subtopic`.`id`',
                            'IJ_Subtopic.is_activated'  => 1
                        ),
                    ),
                );

                break;

            case 'topics':
                $fields[] = 'IJ_Topic.id';

                $model = 'Topic';

                $joins = array(
                    array(
                        'alias'         => 'IJ_' . $entities . 'Subtopic',
                        'table'         => strtolower( $entities ) . '_subtopics',
                        'type'          => 'INNER',
                        'conditions'    => '`' . $entity . '`.`id` = `IJ_' . $entities . 'Subtopic`.`' . strtolower( $entity ) . '_id`',
                    ),
                    array(
                        'alias'         => 'IJ_Subtopic',
                        'table'         => 'subtopics',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_' . $entities . 'Subtopic`.`subtopic_id` = `IJ_Subtopic`.`id`',
                            'IJ_Subtopic.is_activated'  => 1
                        ),
                    ),
                    array(
                        'alias'         => 'IJ_Topic',
                        'table'         => 'topics',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_Subtopic`.`topic_id` = `IJ_Topic`.`id`',
                            'IJ_Topic.is_activated'  => 1
                        ),
                    ),
                );

                break;

            case 'members':
                $fields[] = 'IJ_Member.id';

                $model = 'Member';

                $intermediateTable = ucfirst( ( $entity == 'Organization' ) ? 'org_memberships' : 'people_memberships' );
                $joins = array(
                    array(
                        'alias'         => 'IJ_' . $intermediateTable,
                        'table'         => strtolower( $intermediateTable ),
                        'type'          => 'INNER',
                        'conditions'    => '`' . $entity . '`.`id` = `IJ_' . $intermediateTable . '`.`' . strtolower( $entity ) . '_id`',
                    ),
                    array(
                        'alias'         => 'IJ_Member',
                        'table'         => 'members',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_' . $intermediateTable . '`.`member_id` = `IJ_Member`.`id`',
                        ),
                    ),
                );

                break;

            case 'positions':
                $fields[] = 'IJ_Position.id';

                $model = 'Position';

                $joins = array(
                    array(
                        'alias'         => 'IJ_Position',
                        'table'         => 'positions',
                        'type'          => 'INNER',
                        'conditions'    => array(
                            '`IJ_Position`.`id` = `' . $entity . '`.`position_id`',
                        ),
                    ),
                );


                break;

            }   // switch
        /**
         * Are we displaying the data in a normal year or in a business year?
         * - a normal year starts Jan 01 and ends Dec 31
         * - a business year starts Oct 01 and ends Sept 30 of next year
         */
        $displayAsBusinessYear = isset( $this->params->query['year_type'] ) && ( ( int )$this->params->query['year_type'] == 1 );

        // Do we use the `increased` parameter?
        $bIncreasedResults =  !empty( $this->params->query['results_type'] ) && ( $this->params->query['results_type'] == '1' );

        $this->loadModel( $entity );

        // find the entities
        $allEntities = $this->{$entity}->find( 'all', array(
            'recursive'     => -1,
            'fields'        => $fields,
            'conditions'    => $conditions,
            'joins'         => $joins,
        ) );

        // Business or normal year?
        // If we are in a business year, I will run through all the entities to check if the month is before October
        // In that case, I will decrease the year of that entity because it is attached to the previous business year
        if( $displayAsBusinessYear ) {
            $nEntities = count( $allEntities );
            for( $i = 0; $i < $nEntities; $i++ ) {
                $date = explode( '-', $allEntities[$i][$entity][$dateField] );
                // before October ?
                if( $date[1] < 10 ) {
                    $date[0]--;
                    $allEntities[$i][$entity][$dateField] = implode( '-', $date );
                }
            }
        }

        // What are the start and end years?
        $yearStart = date( 'Y' ) - 1 + 543;
        $yearEnd = date( 'Y' ) + 543;

        if ( !empty(  $this->request->query['filter_since_year'] ) ) {
            $yearStart = ( int )$this->request->query['filter_since_year'];
        }
        if ( !empty(  $this->request->query['filter_until_year'] ) ) {
            $yearEnd = ( int )$this->request->query['filter_until_year'];
        }

        $yearStart -= 543;
        $yearEnd -= 543;

        $values = array();
        $oldValues = array();

        // lets load the model to create the labels on the left column
        $this->loadModel( $model );
        $labels = $this->{$model}->find( 'list', array(
            'order' => array( $model . '.name' => 'ASC' ),
        ) );

        // initialize our data structure
        foreach( $labels as $kLabel => $vLabel ) {
            for($i = $yearStart; $i <= $yearEnd; $i++ ) {
                $values[$kLabel][$i] = 0;
            }
            $oldValues[$kLabel] = 0;
        }

        // now loop through all entities and increment the counters
        foreach ( $allEntities as $oneEntity ) {
            $year = explode( '-', $oneEntity[$entity][$dateField] );
            $year = $year[0];

            // older values,  go to yOldValues
            if( $year < $yearStart ) {
                $oldValues[$oneEntity['IJ_' . $model]['id']]++;
            } else if( $year <= $yearEnd ) {
                $values[$oneEntity['IJ_' . $model]['id']][$year]++;
            }
        }

        // if we display normal values, we have to add the previous years
        if( !$bIncreasedResults ) {

            foreach( $values as $kValue => $vValue ) {
                $values[$kValue][$yearStart + 0] += $oldValues[$kValue];

                for( $i = 1; $i < count( $values[$kValue] ); $i++ ) {
                    $values[$kValue][$yearStart + $i] += $values[$kValue][$yearStart + $i-1];
                }
            }

        }

        $this->set( 'year_start', $yearStart );
        $this->set( 'year_end', $yearEnd );
        $this->set( 'labels', $labels );
        $this->set( 'values', $values );

    }

    /**
     * Send email to admin
     *
     * @author Ting <3musketeersteam@gmail.com>
     * @since 28 January 2014
     */
    public function contact() {

        if ( $this->request->is('post') ) {

            App::uses('CakeEmail', 'Network/Email');
            $receiveEmail = Configure::read('CONTACT_EMAIL');

            $emailMessage = sprintf("ชื่อ : %s <br> หัวข้อ : %s <br><p>%s</p><p>โทรศัพท์ : %s</p><p>อีเมล์: %s</p><p>อาชีพ/หน่วยงาน : %s</p><p>%s</p>",
                        $this->request->data['contact']['name'],
                        $this->request->data['contact']['topic'],
                        $this->request->data['contact']['address'],
                        $this->request->data['contact']['tel'],
                        $this->request->data['contact']['email'],
                        $this->request->data['contact']['career'],
                        $this->request->data['contact']['description']
                    );

            $Email = new CakeEmail('gmail');
            $Email->from( array( Configure::read('SENDER_EMAIL') => __('สำนักงานคณะกรรมการสิทธิมนุษยชนแห่งชาติ')));
            $Email->to($receiveEmail);
            $Email->emailFormat('html');
            $Email->subject(__('ติดต่อจากเว็บไซต์ : ') . $this->request->data['contact']['topic'] );

            if ( !$Email->send($emailMessage) ) {
                $this->Session->setFlash(__('ไม่สามารถส่งอีเมลล์ได้ กรุณาลองใหม่อีกครั้ง'), 'flash-fail');
                return;
            }

            $this->Session->setFlash(__('ส่งอีเมล์เรียบร้อยแล้ว'), 'flash-success');
        }

        $this->set('topicTitle', __('ติดต่อเรา'));
    }

     public function rss_feed() {

        $this->__prepareEntitiesDataForCountry( 'Organization', 'Organizations' );
      //  $this->__prepareEntitiesDataForCountry( 'Person', 'People', false );

        // // count the people for the table on the right side
      //  $allEntities = $this->__getAllEntitiesInCountry( 'Person', 'People' );

        // //Get all region
        // //@todo : accually we can use
        // //          $restTotal = array(1 => 'null', 2 => 'null', 3 => 'null', 4 => 'null', 5 => 'null', 6 => 'null');
        // //        instead of find data in region table.
        // $this->loadModel('Region');
        // $this->Region->recursive = -1;
        // $restTotal = $this->Region->find('all');
        // $restTotal = Hash::combine($restTotal, '{n}.Region.id');
        // //Count entities.
        // foreach( $restTotal as $kRestTotal => $vRestTotal ) {
        //    $restTotal[ $kRestTotal ] = 0;
        // }

        // $this->__countAnotherOrg( $restTotal, $allEntities, 'Province', 'region_' );

        // $this->set('rest_total', $restTotal);
        // $this->set('all_entities', $allEntities);
        // $this->set( 'number_of_people', $this->__countEntities( 'Person', $allEntities ) );

       // $this->__setTargetsInView();
    }


}

Anon7 - 2022
AnonSec Team