<?php
/**
* SocialEngine
*
* @category Application_Core
* @package Core
* @copyright Copyright 2006-2020 Webligo Developments
* @license http://www.socialengine.com/license/
* @version $Id: Membership.php 10068 2013-06-26 23:46:22Z shaun $
* @author John
*/
/**
* @category Application_Core
* @package Core
* @copyright Copyright 2006-2020 Webligo Developments
* @license http://www.socialengine.com/license/
*/
abstract class Core_Model_DbTable_Membership extends Engine_Db_Table
{
protected $_type;
protected $_rows = array();
/**
* @var string The module name of this model (say that 12 times fast)
*/
protected $_moduleName;
/**
* Get the module this model belongs to
*
* @return string The module name of this model
*/
public function getModuleName()
{
if( empty($this->_moduleName) )
{
$class = get_class($this);
if (preg_match('/^([a-z][a-z0-9]*)_/i', $class, $matches)) {
$prefix = $matches[1];
} else {
$prefix = $class;
}
$this->_moduleName = $prefix;
}
return $this->_moduleName;
}
// Tables
/**
* Gets the table associated with this membership type.
*
* @return Engine_Db_Table
*/
public function getTable()
{
return $this;
}
// General
/**
* Gets the row associated with the specified resource/member pair in the db
*
* @param Core_Model_Item_Abstract $resource
* @param User_Model_User $user
* @return Engine_Db_Table_Row|false
*/
public function getRow(Core_Model_Item_Abstract $resource, User_Model_User $user)
{
$id = $resource->getIdentity().'_'.$user->getIdentity();
if( !isset($this->_rows[$id]) )
{
$table = $this->getTable();
$select = $table->select()
->where('resource_id = ?', $resource->getIdentity())
->where('user_id = ?', $user->getIdentity());
$select = $select->limit(1);
$row = $table->fetchRow($select);
//if( $row === null )
//{
// $this->_rows[$id] = false;
//}
//else
//{
$this->_rows[$id] = $row;
//}
}
return $this->_rows[$id];
}
public function clearRows()
{
$this->_rows = array();
return $this;
}
// Configuration
/**
* Does membership require approval of the resource?
*
* @param Core_Model_Item_Abstract $resource
* @return bool
*/
public function isResourceApprovalRequired(Core_Model_Item_Abstract $resource)
{
return true;
}
/**
* Does membership require approval of the user?
*
* @return bool
*/
public function isUserApprovalRequired()
{
return true;
}
// Member management
/**
* Add $user as member to $resource
*
* @param Core_Model_Item_Abstract $resource
* @param User_Model_User $user
* @return Core_Model_DbTable_Membership
*/
public function addMember(Core_Model_Item_Abstract $resource, User_Model_User $user)
{
$this->_isSupportedType($resource);
$row = $this->getRow($resource, $user);
if( null !== $row )
{
throw new Core_Model_Exception('That user is already a member');
}
$id = $resource->getIdentity().'_'.$user->getIdentity();
$row = $this->getTable()->createRow();
$row->setFromArray(array(
'resource_id' => $resource->getIdentity(),
'user_id' => $user->getIdentity(),
'resource_approved' => !$this->isResourceApprovalRequired($resource),
'user_approved' => 0,
'active' => 0
));
$row->save();
$this->_rows[$id] = $row;
$this->_checkActive($resource, $user);
return $this;
}
/**
* Remove $user as member of $resource
*
* @param Core_Model_Item_Abstract $resource
* @param User_Model_User $user
* @return Core_Model_DbTable_Membership
*/
public function removeMember(Core_Model_Item_Abstract $resource, User_Model_User $user)
{
$this->_isSupportedType($resource);
$row = $this->getRow($resource, $user);
if( null === $row )
{
throw new Core_Model_Exception("Membership does not exist");
}
if( isset($resource->member_count) && $row->active )
{
$resource->member_count--;
$resource->save();
}
$row->delete();
return $this;
}
public function removeMembers(Core_Model_Item_Abstract $resource, $ids)
{
// @todo
}
public function removeAllMembers(Core_Model_Item_Abstract $resource)
{
$this->getTable()->delete(array(
'resource_id = ?' => $resource->getIdentity()
));
if( isset($resource->member_count) ) {
$resource->member_count = 0;
$resource->save();
}
return $this;
}
/**
* Set membership as being approved by the resource
*
* @param Core_Model_Item_Abstract $resource
* @param User_Model_User $user
* @return Core_Model_DbTable_Membership
*/
public function setResourceApproved(Core_Model_Item_Abstract $resource, User_Model_User $user)
{
$this->_isSupportedType($resource);
$row = $this->getRow($resource, $user);
if( null === $row )
{
throw new Core_Model_Exception("Membership does not exist");
}
if( !$row->resource_approved )
{
$row->resource_approved = true;
if( $row->resource_approved && $row->user_approved )
{
$row->active = true;
if( isset($resource->member_count) )
{
$resource->member_count++;
$resource->save();
}
}
$this->_checkActive($resource, $user);
$row->save();
}
return $this;
}
/**
* Set membership as being approved by the user
*
* @param Core_Model_Item_Abstract $resource
* @param User_Model_User $user
* @return Core_Model_DbTable_Membership
*/
public function setUserApproved(Core_Model_Item_Abstract $resource, User_Model_User $user)
{
$this->_isSupportedType($resource);
$row = $this->getRow($resource, $user);
if( null === $row )
{
throw new Core_Model_Exception("Membership does not exist");
}
if( !$row->user_approved )
{
$row->user_approved = true;
if( $row->resource_approved && $row->user_approved )
{
$row->active = true;
if( isset($resource->member_count) )
{
$resource->member_count++;
$resource->save();
}
}
$this->_checkActive($resource, $user);
$row->save();
}
return $this;
}
// Member info
/**
* Checks if specified user is a member of resource. Set $active to true/false
* to check for approved status, or null for either.
*
* @param Core_Model_Item_Abstract $resource
* @param User_Model_User $user
* @param bool|null $active
* @return bool
*/
public function isMember(Core_Model_Item_Abstract $resource, User_Model_User $user, $active = null)
{
$this->_isSupportedType($resource);
$row = $this->getRow($resource, $user);
if ($row === null)
{
return false;
}
if( null === $active )
{
return true;
}
return ( $active == $row->active );
}
public function getMemberInfo(Core_Model_Item_Abstract $resource, User_Model_User $user)
{
return $this->getRow($resource, $user);
}
/**
* Gets the number of members a resource has
*
* @param Core_Model_Item_Abstract $resource
* @param bool $active
* @return int
*/
public function getMemberCount(Core_Model_Item_Abstract $resource, $active = true, $other_conditions = array())
{
if( isset($resource->member_count) && $active && empty($other_conditions))
{
return $resource->member_count;
}
else
{
$table = $this->getTable();
$select = new Zend_Db_Select($table->getAdapter());
$select->from($table->info('name'), new Zend_Db_Expr('COUNT(user_id) as member_count'))
->where('resource_id = ?', $resource->getIdentity());
if( null != $active )
{
$select->where('active = ?', (bool) $active);
}
foreach ($other_conditions as $condition_name=>$condition_value)
{
$select = $select->where($condition_name . ' = ?', $condition_value);
}
$row = $table->getAdapter()->fetchRow($select);
return $row['member_count'];
}
}
/**
* Gets members Ids that belong to resource
*
* @param Core_Model_Item_Abstract $resource
* @param bool|null $active
* @return Engine_Db_Table_Rowset
*/
public function getMembersIds(Core_Model_Item_Abstract $resource, $active = true)
{
$ids = array();
foreach( $this->getMembersInfo($resource, $active) as $row )
{
$ids[] = $row->user_id;
}
return $ids;
}
/**
* Gets members that belong to resource
*
* @param Core_Model_Item_Abstract $resource
* @param bool|null $active
* @return Engine_Db_Table_Rowset
*/
public function getMembers(Core_Model_Item_Abstract $resource, $active = true)
{
$ids = $this->getMembersIds($resource, $active);
return Engine_Api::_()->getItemTable('user')->find($ids);
}
/**
* Gets membership info for members that belong to resource
*
* @param Core_Model_Item_Abstract $resource
* @param bool|null $active
* @return Engine_Db_Table_Rowset
*/
public function getMembersInfo(Core_Model_Item_Abstract $resource, $active = true)
{
$table = $this->getTable();
$select = $table->select()->where('resource_id = ?', $resource->getIdentity());
if( $active !== null )
{
$select->where('active = ?', (bool) $active);
}
return $table->fetchAll($select);
}
public function getMembersSelect(Core_Model_Item_Abstract $resource, $active = true)
{
$table = $this->getTable();
$select = $table->select()
->where('resource_id = ?', $resource->getIdentity())
;
if( $active !== null )
{
$select->where('active = ?', (bool) $active);
}
return $select;
}
public function getMembersOfSelect(Core_Model_Item_Abstract $resource, $active = true)
{
$table = $this->getTable();
$select = $table->select()
->where('user_id = ?', $resource->getIdentity())
;
if( $active !== null )
{
$select->where('active = ?', (bool) $active);
}
return $select;
}
public function getMembersObjectSelect(Core_Model_Item_Abstract $resource, $active = true)
{
$table = Engine_Api::_()->getDbtable('users', 'user');
$subtable = $this->getTable();
$tableName = $table->info('name');
$subtableName = $subtable->info('name');
$select = $table->select()
->from($tableName)
->joinRight($subtableName, '`'.$subtableName.'`.`user_id` = `'.$tableName.'`.`user_id`', null)
->where('`'.$subtableName.'`.`resource_id` = ?', $resource->getIdentity())
;
if( $active !== null )
{
$select->where('`'.$subtableName.'`.`active` = ?', (bool) $active);
}
return $select;
}
/**
* Gets resources that $user is a member of in the current type.
*
* @param User_Model_User $user
* @param bool|null $active
* @return Engine_Db_Table_Rowset
*/
public function getMembershipsOf(User_Model_User $user, $active = true)
{
$ids = $this->getMembershipsOfIds($user, $active);
return Engine_Api::_()->getItemTable($this->_type)->find($ids);
}
public function getMembershipsOfIds(User_Model_User $user, $active = true)
{
$ids = array();
$rows = $this->getMembershipsOfInfo($user, $active);
foreach( $rows as $row )
{
$ids[] = $row->resource_id;
}
return $ids;
}
/**
* Gets resource membership info that $user is a member of in the current type.
*
* @param User_Model_User $user
* @param bool|null $active
* @return Engine_Db_Table_Rowset
*/
public function getMembershipsOfInfo(User_Model_User $user, $active = true)
{
$table = $this->getTable();
$select = $table->select()->where('user_id = ?', $user->getIdentity());
if( $active !== null )
{
$select->where('active = ?', (bool) $active);
}
return $table->fetchAll($select);
}
public function getMembershipsOfSelect(User_Model_User $user, $active = true)
{
$itemTable = Engine_Api::_()->getItemTable($this->_type);
$table = $this->getTable();
$itName = $itemTable->info('name');
$mtName = $table->info('name');
$col = current($itemTable->info('primary'));
$select = $itemTable->select()
->from($itName)
->joinRight($mtName, "`{$mtName}`.`resource_id` = `{$itName}`.`{$col}`", null)
->where("`{$mtName}`.`user_id` = ?", $user->getIdentity())
;
if( $active !== null )
{
$select->where("`{$mtName}`.`active` = ?", (bool) $active);
}
return $select;
}
// Utility
/**
* Used to check and update active status after addMember, set*Approved
*
* @param Core_Model_Item_Abstract $resource
* @param User_Model_User $user
*/
protected function _checkActive(Core_Model_Item_Abstract $resource, User_Model_User $user)
{
$row = $this->getRow($resource, $user);
if( null === $row )
{
throw new Core_Model_Exception("Membership does not exist");
}
if( $row->resource_approved && $row->user_approved && !$row->active )
{
$row->active = true;
$row->save();
if( isset($resource->member_count) ) {
$resource->member_count++;
$resource->save();
}
}
}
/**
* Checks if resource is of the proper type.
*
* @param Core_Model_Item_Abstract $resource
* @throws Core_Model_Exception
*/
protected function _isSupportedType(Core_Model_Item_Abstract $resource)
{
if( $resource->getType() !== $this->_type )
{
throw new Core_Model_Exception(sprintf('Type "%s" is not supported', $resource->getType()));
}
}
}