<?php
#BEGIN_LICENSE
#-------------------------------------------------------------------------
# Module: MAMS (c) 2020-2021 by CMS Made Simple Foundation
#  An add-on module for CMS Made Simple to provide useful functions
#  and commonly used gui capabilities to other modules.
#-------------------------------------------------------------------------
# A fork of:
#
# Module: FrontEndUsers (c) 2008-2014 by Robert Campbell
#         (calguy1000@cmsmadesimple.org)
#
#-------------------------------------------------------------------------
#
# CMSMS - CMS Made Simple is (c) 2006 - 2021 by CMS Made Simple Foundation
# CMSMS - CMS Made Simple is (c) 2005 by Ted Kulp (wishy@cmsmadesimple.org)
# Visit the CMSMS Homepage at: http://www.cmsmadesimple.org
#
#-------------------------------------------------------------------------
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# However, as a special exception to the GPL, this software is distributed
# as an addon module to CMS Made Simple.  You may not use this software
# in any Non GPL version of CMS Made simple, or in any version of CMS
# Made simple that does not indicate clearly and obviously in its admin
# section that the site was built with CMS Made simple.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Or read it online: http://www.gnu.org/licenses/licenses.html#GPL
#
#-------------------------------------------------------------------------
#END_LICENSE

namespace MAMS;

class user implements \ArrayAccess
{
  private $_data = [
    'id'               => NULL,
    'username'         => NULL,
    'createdate'       => NULL,
    'expires'          => NULL,
    'nonstd'           => FALSE,
    'disabled'         => FALSE,
    'force_newpw'      => FALSE,
    'force_chsettings' => FALSE,
    'must_validate'    => FALSE,
    'loggedin'         => NULL
  ];
    private $_new_password;
    private $_props;
    private $_groups; // lazy loaded.
    private $_dirty;
  
  #[\ReturnTypeWillChange]
    public function OffsetGet($key)
    {
        return $this->__get($key);
    }
  
  #[\ReturnTypeWillChange]
    public function OffsetSet($key,$val)
    {
        return $this->__set($key,$val);
    }
  #[\ReturnTypeWillChange]
    public function OffsetUnset($key) { /* do nothing */ }
  
  #[\ReturnTypeWillChange]
    public function OffsetExists($key) {
        return isset($this->_data[$key]);
    }

    public function __get($key)
    {
        switch( $key ) {
        case 'id':
            return (int) $this->_data[$key];

        case 'username':
            return \trim((string)$this->_data[$key]);

        case 'createdate_ts':
            if( !$this->_data['createdate'] ) return 0;
            $db = \CmsApp::get_instance()->GetDb();
            return $db->UnixTimeStamp($this->_data['createdate']);

        case 'createdate_str': // db date
            return trim((string)$this->_data['createdate']);

        case 'expires_ts':
            if( !$this->_data['expires'] ) return 0;
            $db = \CmsApp::get_instance()->GetDb();
            return $db->UnixTimeStamp($this->_data['expires']);

        case 'expires_str': // db date
            return trim((string)$this->_data['expires']);

        case 'nonstd':
        case 'disabled':
        case 'force_newpw':
        case 'force_chsettings':
        case 'must_validate':
        case 'loggedin':
            return (bool) $this->_data[$key];

        default:
            throw new \LogicException("$key is not a gettable member of ".__CLASS__);
        }
    }

    public function is_expired()
    {
        return ($this->expires_ts < time());
    }

    public function get_property($key)
    {
        $key = trim($key);
        if( !$key ) throw new \LogicException('Invalid key passed to '.__METHOD__);
        if( isset($this->_props[$key]) ) return $this->_props[$key];
    }

    public function get_properties()
    {
      if( !is_array($this->_props) ) $this->_props = [];
      
      return $this->_props;
    }

    public function get_groups()
    {
        if( !$this->_groups ) {
            if( !$this->id ) return;
            $mod = \cms_utils::get_module(MOD_MAMS);
            $tmp = $mod->GetMemberGroupsArray($this->id);
            if( $tmp && count($tmp) ) {
                $out = array();
                foreach( $tmp as $one ) $out[] = (int) $one['groupid'];
                $this->_groups = $out;
            }
        }
        return $this->_groups;
    }

    public function memberof($gid)
    {
        $gid = (int) $gid;
        if( $gid < 1 ) throw new \LogicException('Invalid gid passed to '.__METHOD__);
        $groups = $this->get_groups();
        return in_arra($gid,$groups);
    }

    public static function load($user_id)
    {
        $user_id = (int) $user_id;
        if( $user_id < 1 ) throw new \LogicException('Invalid user_id passed to '.__METHOD__);

        $row = \mams_user_cache::get_user($user_id,TRUE);
        $obj = new self();

        $keys = array_keys($obj->_data);
        foreach( $keys as $key ) {
            switch( $key ) {
            case 'id':
                $obj->_data[$key] = (int) $row[$key];
            case 'username':
            case 'createdate':
            case 'expires':
                $obj->_data[$key] = trim($row[$key]);
                break;

            case 'nonstd':
            case 'disabled':
            case 'force_newpw':
            case 'force_chsettings':
            case 'must_validate':
            case 'loggedin':
                $obj->_data[$key] = false;
                if( isset($row[$key]) ) $obj->_data[$key] = (bool) $row[$key];
                break;
            }
        }

        // note: encrypted properties are already decrypted here.
      if(isset($row['fprops']) && count($row['fprops']))
      {
        $obj->_props = [];
        foreach($row['fprops'] as $prop)
        {
          $obj->_props[$prop['title']] = $prop['data'];
        }
      }
      else
      {
        if( empty($obj->_props) ) $obj->_props = [];
      }

        return $obj;
    }
}