Beispiel #1
0
 protected function _getModules()
 {
     $modules = array('forum' => 2015121802, 'oauth2' => 2015121501, 'subscription' => 2014092301);
     $option = bdApi_Data_Helper_Core::safeGetSession()->getOAuthClientOption('allow_search_indexing');
     if (!empty($option)) {
         $modules['search/indexing'] = 2015091601;
     }
     return $modules;
 }
Beispiel #2
0
 public function setVisitorLanguage($languageId)
 {
     if ($this->get('user_id') > 0) {
         // because XenForo ignore session language id if user is logged in
         // we have to override its value here
         // NOTE: the load_class for XenForo_Visitor requires 1.2.0+
         $session = bdApi_Data_Helper_Core::safeGetSession();
         $requestLanguageId = $session->get('languageId');
         if ($requestLanguageId > 0) {
             $languageId = $requestLanguageId;
         }
     }
     return parent::setVisitorLanguage($languageId);
 }
Beispiel #3
0
 public function actionPutIndex()
 {
     $input = $this->_input->filter(array('password' => XenForo_Input::STRING, 'password_old' => XenForo_Input::STRING, 'password_algo' => XenForo_Input::STRING, 'user_email' => XenForo_Input::STRING, 'username' => XenForo_Input::STRING, 'primary_group_id' => XenForo_Input::UINT, 'secondary_group_ids' => array(XenForo_Input::UINT, 'array' => true), 'user_dob_day' => XenForo_Input::UINT, 'user_dob_month' => XenForo_Input::UINT, 'user_dob_year' => XenForo_Input::UINT, 'user_fields' => XenForo_Input::ARRAY_SIMPLE));
     $user = $this->_getUserOrError();
     $visitor = XenForo_Visitor::getInstance();
     $session = bdApi_Data_Helper_Core::safeGetSession();
     $isAdmin = $session->checkScope(bdApi_Model_OAuth2::SCOPE_MANAGE_SYSTEM) && $visitor->hasAdminPermission('user');
     $requiredAuth = 0;
     if (!empty($input['password'])) {
         $requiredAuth++;
     }
     if (!empty($input['user_email'])) {
         $requiredAuth++;
     }
     if ($requiredAuth > 0) {
         $isAuth = false;
         if ($isAdmin && $visitor['user_id'] != $user['user_id']) {
             $isAuth = true;
         } elseif (!empty($input['password_old'])) {
             $auth = $this->_getUserModel()->getUserAuthenticationObjectByUserId($user['user_id']);
             if (!empty($auth)) {
                 $passwordOld = bdApi_Crypt::decrypt($input['password_old'], $input['password_algo']);
                 if ($auth->hasPassword() && $auth->authenticate($user['user_id'], $passwordOld)) {
                     $isAuth = true;
                 }
             }
         }
         if (!$isAuth) {
             return $this->responseError(new XenForo_Phrase('bdapi_slash_users_requires_password_old'), 403);
         }
     }
     /* @var $writer XenForo_DataWriter_User */
     $writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
     $writer->setExistingData($user, true);
     if ($isAdmin) {
         $writer->setOption(XenForo_DataWriter_User::OPTION_ADMIN_EDIT, true);
     }
     if (!empty($input['password'])) {
         $password = bdApi_Crypt::decrypt($input['password'], $input['password_algo']);
         $writer->setPassword($password, $password);
     }
     if (!empty($input['user_email'])) {
         $writer->set('email', $input['user_email']);
         if ($writer->isChanged('email') && XenForo_Application::getOptions()->get('registrationSetup', 'emailConfirmation') && !$isAdmin) {
             switch ($writer->get('user_state')) {
                 case 'moderated':
                 case 'email_confirm':
                     $writer->set('user_state', 'email_confirm');
                     break;
                 default:
                     $writer->set('user_state', 'email_confirm_edit');
             }
         }
     }
     if (!empty($input['username'])) {
         $writer->set('username', $input['username']);
         if ($writer->isChanged('username') && !$isAdmin) {
             return $this->responseError(new XenForo_Phrase('bdapi_slash_users_denied_username'), 403);
         }
     }
     if ($input['primary_group_id'] > 0) {
         $userGroups = $this->_getUserGroupModel()->getAllUserGroups();
         if (!isset($userGroups[$input['primary_group_id']])) {
             return $this->responseError(new XenForo_Phrase('requested_user_group_not_found'));
         }
         if (!empty($input['secondary_group_ids'])) {
             foreach ($input['secondary_group_ids'] as $secondaryGroupId) {
                 if (!isset($userGroups[$secondaryGroupId])) {
                     return $this->responseError(new XenForo_Phrase('requested_user_group_not_found'));
                 }
             }
         }
         $writer->set('user_group_id', $input['primary_group_id']);
         $writer->setSecondaryGroups($input['secondary_group_ids']);
     }
     if (!empty($input['user_dob_day']) && !empty($input['user_dob_month']) && !empty($input['user_dob_year'])) {
         $writer->set('dob_day', $input['user_dob_day']);
         $writer->set('dob_month', $input['user_dob_month']);
         $writer->set('dob_year', $input['user_dob_year']);
         $hasExistingDob = false;
         $hasExistingDob = $hasExistingDob || !!$writer->getExisting('dob_day');
         $hasExistingDob = $hasExistingDob || !!$writer->getExisting('dob_month');
         $hasExistingDob = $hasExistingDob || !!$writer->getExisting('dob_year');
         if ($hasExistingDob && ($writer->isChanged('dob_day') || $writer->isChanged('dob_month') || $writer->isChanged('dob_year')) && !$isAdmin) {
             // setting new dob is fine but changing dob requires admin permission
             return $this->responseError(new XenForo_Phrase('bdapi_slash_users_denied_dob'), 403);
         }
     }
     if (!empty($input['user_fields'])) {
         $profileFieldsInput = new XenForo_Input($input['user_fields']);
         $profileFields = $profileFieldsInput->filter(array('about' => XenForo_Input::STRING, 'homepage' => XenForo_Input::STRING, 'location' => XenForo_Input::STRING, 'occupation' => XenForo_Input::STRING));
         $writer->bulkSet($profileFields);
         $writer->setCustomFields($input['user_fields']);
     }
     $writer->preSave();
     if (!$isAdmin) {
         if ($writer->isChanged('user_group_id') || $writer->isChanged('secondary_group_ids')) {
             // this has to be checked here because `secondary_group_ids` only get set within preSave()
             return $this->responseError(new XenForo_Phrase('bdapi_slash_users_denied_user_group'), 403);
         }
     }
     $writer->save();
     $user = $writer->getMergedData();
     if ($writer->isChanged('email') && in_array($user['user_state'], array('email_confirm', 'email_confirm_edit'))) {
         /* @var $userConfirmationModel XenForo_Model_UserConfirmation */
         $userConfirmationModel = $this->getModelFromCache('XenForo_Model_UserConfirmation');
         $userConfirmationModel->sendEmailConfirmation($user);
     }
     return $this->responseMessage(new XenForo_Phrase('changes_saved'));
 }
Beispiel #4
0
 public static function buildApiLink($type, $data = null, array $extraParams = array(), $skipPrepend = false)
 {
     // the type MUST BE full:type
     // NOTE: this is the opposite with public links
     if (strpos($type, 'canonical:') === 0) {
         // replace canonical: with full:
         $type = str_replace('canonical:', 'full:', $type);
     } elseif (strpos($type, 'full:') === false) {
         // enforce full:
         $type = 'full:' . $type;
     }
     // auto appends oauth_token param from the session
     if (!isset($extraParams['oauth_token'])) {
         $session = bdApi_Data_Helper_Core::safeGetSession();
         if (!empty($session)) {
             $oauthToken = $session->getOAuthTokenText();
             if (!empty($oauthToken) && !empty($_REQUEST['oauth_token']) && $_REQUEST['oauth_token'] === $oauthToken) {
                 // only append token to built link if the current request has token in query too
                 // this will prevent token in links if it's requested with OTT, token in Auth header
                 // or token in body (PUT/POST requests)
                 $extraParams['oauth_token'] = $oauthToken;
             }
         }
     }
     $type = XenForo_Link::_checkForFullLink($type, $fullLink, $fullLinkPrefix);
     $link = XenForo_Link::_buildLink(self::API_LINK_GROUP, $type, $data, $extraParams);
     $queryString = XenForo_Link::buildQueryString($extraParams);
     if ($link instanceof XenForo_Link) {
         $canPrependFull = $link->canPrependFull();
     } else {
         $canPrependFull = true;
         if (strpos($link, '#') !== false) {
             list($link, $hash) = explode('#', $link);
         }
     }
     if ($queryString !== '' && $link !== '') {
         $append = "?{$link}&{$queryString}";
     } else {
         // 1 or neither of these has content
         $append = $link . $queryString;
         if ($append !== '') {
             $append = "?{$append}";
         }
     }
     if ($skipPrepend) {
         $outputLink = $append;
     } else {
         $outputLink = 'index.php' . $append;
     }
     if ($fullLink && $canPrependFull) {
         $outputLink = $fullLinkPrefix . $outputLink;
     }
     // deal with a hash in the $type {xen:link prefix#hash..}
     if (($hashPos = strpos($type, '#')) !== false) {
         $hash = substr($type, $hashPos + 1);
     }
     if ($outputLink === '') {
         $outputLink = '.';
     }
     return $outputLink . (empty($hash) ? '' : '#' . $hash);
 }
Beispiel #5
0
 protected function _prepareSessionActivityForApi(&$controllerName, &$action, array &$params)
 {
     $controllerName = 'bdApi_ControllerApi_Index';
     $action = '';
     $params = array();
     $session = bdApi_Data_Helper_Core::safeGetSession();
     if (!empty($session)) {
         $params['client_id'] = $session->getOAuthClientId();
     }
 }
Beispiel #6
0
 public function prepareApiDataForUser(array $user)
 {
     $visitor = XenForo_Visitor::getInstance();
     $session = bdApi_Data_Helper_Core::safeGetSession();
     /* @var $userGroupModel bdApi_XenForo_Model_UserGroup */
     $userGroupModel = $this->getModelFromCache('XenForo_Model_UserGroup');
     /* @var $conversationModel XenForo_Model_Conversation */
     $conversationModel = $this->getModelFromCache('XenForo_Model_Conversation');
     $hasAdminScope = !empty($session) && $session->checkScope(bdApi_Model_OAuth2::SCOPE_MANAGE_SYSTEM);
     $isAdminRequest = $hasAdminScope && $visitor->hasAdminPermission('user');
     $prepareProtectedData = $user['user_id'] == $visitor->get('user_id') || $isAdminRequest;
     $publicKeys = array('user_id' => 'user_id', 'username' => 'username', 'message_count' => 'user_message_count', 'register_date' => 'user_register_date', 'like_count' => 'user_like_count');
     if ($prepareProtectedData) {
         $publicKeys = array_merge($publicKeys, array('email' => 'user_email', 'alerts_unread' => 'user_unread_notification_count', 'dob_day' => 'user_dob_day', 'dob_month' => 'user_dob_month', 'dob_year' => 'user_dob_year'));
         if (!empty($session) and $session->checkScope(bdApi_Model_OAuth2::SCOPE_PARTICIPATE_IN_CONVERSATIONS)) {
             // xf_user
             $publicKeys['conversations_unread'] = 'user_unread_conversation_count';
         }
     }
     $data = bdApi_Data_Helper_Core::filter($user, $publicKeys);
     $data['user_title'] = XenForo_Template_Helper_Core::helperUserTitle($user);
     if (isset($user['user_state']) and isset($user['is_banned'])) {
         if (!empty($user['is_banned'])) {
             $data['user_is_valid'] = false;
             $data['user_is_verified'] = true;
         } else {
             switch ($user['user_state']) {
                 case 'valid':
                     $data['user_is_valid'] = true;
                     $data['user_is_verified'] = true;
                     break;
                 case 'email_confirm':
                 case 'email_confirm_edit':
                     $data['user_is_valid'] = true;
                     $data['user_is_verified'] = false;
                     break;
                 case 'moderated':
                     $data['user_is_valid'] = false;
                     $data['user_is_verified'] = false;
                     break;
             }
         }
     }
     $data['user_is_followed'] = !empty($user['bdapi_user_is_followed']);
     if ($this->canViewUserCurrentActivity($user)) {
         $data['user_last_seen_date'] = $user['last_activity'];
     } else {
         // user hides his/her activity, use the register date value instead
         // (IMHO using 0 will make it too obvious that activity is hidden)
         $data['user_last_seen_date'] = $user['register_date'];
     }
     $data['links'] = array('permalink' => XenForo_Link::buildPublicLink('members', $user), 'detail' => bdApi_Data_Helper_Core::safeBuildApiLink('users', $user), 'avatar' => XenForo_Template_Helper_Core::callHelper('avatar', array($user, 'm', false, true)), 'avatar_big' => XenForo_Template_Helper_Core::callHelper('avatar', array($user, 'l', false, true)), 'avatar_small' => XenForo_Template_Helper_Core::callHelper('avatar', array($user, 's', false, true)), 'followers' => bdApi_Data_Helper_Core::safeBuildApiLink('users/followers', $user), 'followings' => bdApi_Data_Helper_Core::safeBuildApiLink('users/followings', $user), 'ignore' => bdApi_Data_Helper_Core::safeBuildApiLink('users/ignore', $user));
     $data['permissions'] = array('edit' => $prepareProtectedData, 'follow' => $user['user_id'] != $visitor->get('user_id') && $visitor->canFollow());
     /** @var XenForo_Model_UserIgnore $ignoreModel */
     $ignoreModel = $this->getModelFromCache('XenForo_Model_UserIgnore');
     $data['permissions']['ignore'] = $ignoreModel->canIgnoreUser($visitor->get('user_id'), $user);
     $data['user_is_ignored'] = $visitor->isIgnoring($user['user_id']);
     $data['user_is_visitor'] = $user['user_id'] == $visitor->get('user_id');
     if ($prepareProtectedData) {
         if (isset($user['timezone'])) {
             $dtz = new DateTimeZone($user['timezone']);
             $dt = new DateTime('now', $dtz);
             $data['user_timezone_offset'] = $dtz->getOffset($dt);
         }
         $auth = $this->getUserAuthenticationObjectByUserId($user['user_id']);
         $data['user_has_password'] = $auth->hasPassword();
         $data['user_fields'] = $this->prepareApiDataForUserFields($user);
         $thisUserGroups = array();
         $userGroups = $userGroupModel->bdApi_getAllUserGroupsCached();
         foreach ($userGroups as $userGroup) {
             if ($this->isMemberOfUserGroup($user, $userGroup['user_group_id'])) {
                 $thisUserGroups[] = $userGroup;
             }
         }
         $data['user_groups'] = $userGroupModel->prepareApiDataForUserGroups($thisUserGroups);
         foreach ($data['user_groups'] as &$userGroupRef) {
             if ($userGroupRef['user_group_id'] == $user['user_group_id']) {
                 $userGroupRef['is_primary_group'] = true;
             } else {
                 $userGroupRef['is_primary_group'] = false;
             }
         }
         $data['self_permissions'] = array('create_conversation' => $conversationModel->canStartConversations(), 'upload_attachment_conversation' => $conversationModel->canUploadAndManageAttachment());
         $data['edit_permissions'] = array('password' => true, 'user_email' => true, 'username' => false, 'user_title' => false, 'primary_group_id' => false, 'secondary_group_ids' => false, 'user_dob_day' => false, 'user_dob_month' => false, 'user_dob_year' => false, 'user_fields' => true);
         if ($isAdminRequest) {
             $data['edit_permissions'] = array_merge($data['edit_permissions'], array('username' => true, 'user_title' => true, 'primary_group_id' => true, 'secondary_group_ids' => true));
         }
         if (empty($data['user_dob_day']) && empty($data['user_dob_month']) && empty($data['user_dob_year']) || $isAdminRequest) {
             $data['edit_permissions'] = array_merge($data['edit_permissions'], array('user_dob_day' => true, 'user_dob_month' => true, 'user_dob_year' => true));
         }
     }
     /** @var XenForo_Model_UserProfile $userProfileModel */
     $userProfileModel = $this->getModelFromCache('XenForo_Model_UserProfile');
     if ($userProfileModel->canViewProfilePosts($user)) {
         $data['links']['timeline'] = bdApi_Data_Helper_Core::safeBuildApiLink('users/timeline', $user);
         if ($user['user_id'] == $visitor->get('user_id')) {
             $data['permissions']['profile_post'] = $visitor->canUpdateStatus();
         } else {
             $data['permissions']['profile_post'] = $userProfileModel->canPostOnProfile($user);
         }
     }
     return $data;
 }
Beispiel #7
0
 public function actionPostIndexing()
 {
     $input = $this->_input->filter(array('content_type' => XenForo_Input::STRING, 'content_id' => XenForo_Input::UINT, 'title' => XenForo_Input::STRING, 'body' => XenForo_Input::STRING, 'date' => array(XenForo_Input::UINT, 'default' => XenForo_Application::$time), 'link' => XenForo_Input::STRING, 'extra_data' => XenForo_Input::ARRAY_SIMPLE));
     $session = bdApi_Data_Helper_Core::safeGetSession();
     $option = $session->getOAuthClientOption('allow_search_indexing');
     if (empty($option)) {
         return $this->responseNoPermission();
     }
     $dbKeys = array('client_id' => $session->getOAuthClientId(), 'content_type' => $input['content_type'], 'content_id' => $input['content_id']);
     /** @var bdApi_Model_ClientContent $clientContentModel */
     $clientContentModel = $this->getModelFromCache('bdApi_Model_ClientContent');
     $existingContents = $clientContentModel->getClientContents($dbKeys);
     $existingContent = null;
     if (!empty($existingContents)) {
         $existingContent = reset($existingContents);
     }
     $dw = XenForo_DataWriter::create('bdApi_DataWriter_ClientContent');
     if (!empty($existingContent)) {
         $dw->setExistingData($existingContent, true);
         $input['extra_data'] = array_merge($existingContent['extraData'], $input['extra_data']);
     } else {
         $dw->bulkSet($dbKeys);
     }
     $dw->set('title', $input['title']);
     $dw->set('body', $input['body']);
     $dw->set('date', $input['date']);
     $dw->set('link', $input['link']);
     $dw->set('extra_data', $input['extra_data']);
     if ($dw->isInsert() || XenForo_Visitor::getUserId() > 0) {
         $dw->set('user_id', XenForo_Visitor::getUserId());
     }
     $dw->preSave();
     if ($dw->hasErrors()) {
         return $this->responseErrors($dw->getErrors(), 400);
     }
     $dw->save();
     return $this->responseMessage(new XenForo_Phrase('changes_saved'));
 }
Beispiel #8
0
 public function actionPutIndex()
 {
     $user = $this->_getUserOrError();
     $visitor = XenForo_Visitor::getInstance();
     $input = $this->_input->filter(array('password_old' => XenForo_Input::STRING, 'password_algo' => XenForo_Input::STRING, 'user_email' => XenForo_Input::STRING, 'username' => XenForo_Input::STRING, 'password' => XenForo_Input::STRING, 'user_dob_day' => XenForo_Input::UINT, 'user_dob_month' => XenForo_Input::UINT, 'user_dob_year' => XenForo_Input::UINT));
     $session = bdApi_Data_Helper_Core::safeGetSession();
     $isAdmin = $session->checkScope(bdApi_Model_OAuth2::SCOPE_MANAGE_SYSTEM) && $visitor->hasAdminPermission('user');
     $isAuth = false;
     if ($isAdmin && $visitor['user_id'] != $user['user_id']) {
         $isAuth = true;
     } elseif (!empty($input['password_old'])) {
         $auth = $this->_getUserModel()->getUserAuthenticationObjectByUserId($user['user_id']);
         if (!empty($auth)) {
             $passwordOld = bdApi_Crypt::decrypt($input['password_old'], $input['password_algo']);
             if ($auth->hasPassword() && $auth->authenticate($user['user_id'], $passwordOld)) {
                 $isAuth = true;
             }
         }
     }
     if (!$isAuth) {
         return $this->responseNoPermission();
     }
     /* @var $writer XenForo_DataWriter_User */
     $writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
     $writer->setExistingData($user, true);
     if (!empty($input['user_email'])) {
         $writer->set('email', $input['user_email']);
         if ($writer->isChanged('email') && XenForo_Application::getOptions()->get('registrationSetup', 'emailConfirmation') && !$isAdmin) {
             switch ($writer->get('user_state')) {
                 case 'moderated':
                 case 'email_confirm':
                     $writer->set('user_state', 'email_confirm');
                     break;
                 default:
                     $writer->set('user_state', 'email_confirm_edit');
             }
         }
     }
     if (!empty($input['username'])) {
         if (!$isAdmin) {
             return $this->responseNoPermission();
         }
         $writer->set('username', $input['username']);
     }
     if (!empty($input['password'])) {
         $password = bdApi_Crypt::decrypt($input['password'], $input['password_algo']);
         $writer->setPassword($password, $password);
     }
     if (!empty($input['user_dob_day']) && !empty($input['user_dob_month']) && !empty($input['user_dob_year'])) {
         $hasExistingDob = false;
         $hasExistingDob = $hasExistingDob || !!$writer->getExisting('dob_day');
         $hasExistingDob = $hasExistingDob || !!$writer->getExisting('dob_month');
         $hasExistingDob = $hasExistingDob || !!$writer->getExisting('dob_year');
         if ($hasExistingDob) {
             if (!$isAdmin) {
                 // changing dob requires admin permission
                 return $this->responseNoPermission();
             }
         } else {
             // new dob just needs auth
         }
         $writer->set('dob_day', $input['user_dob_day']);
         $writer->set('dob_month', $input['user_dob_month']);
         $writer->set('dob_year', $input['user_dob_year']);
     }
     if (!$writer->hasChanges()) {
         return $this->responseError(new XenForo_Phrase('error_occurred_or_request_stopped'), 400);
     }
     $writer->save();
     $user = $writer->getMergedData();
     if ($writer->isChanged('email') && in_array($user['user_state'], array('email_confirm', 'email_confirm_edit'))) {
         /* @var $userConfirmationModel XenForo_Model_UserConfirmation */
         $userConfirmationModel = $this->getModelFromCache('XenForo_Model_UserConfirmation');
         $userConfirmationModel->sendEmailConfirmation($user);
     }
     return $this->responseMessage(new XenForo_Phrase('changes_saved'));
 }
Beispiel #9
0
 protected function _getClientOrError()
 {
     /* @var $oauth2Model bdApi_Model_OAuth2 */
     $oauth2Model = $this->getModelFromCache('bdApi_Model_OAuth2');
     $session = bdApi_Data_Helper_Core::safeGetSession();
     $oauthClientId = $session->getOAuthClientId();
     $client = null;
     if (empty($oauthClientId)) {
         $inputClientId = $this->_input->filterSingle('client_id', XenForo_Input::STRING);
         $inputClientSecret = $this->_input->filterSingle('client_secret', XenForo_Input::STRING);
         if (!empty($inputClientId) and !empty($inputClientSecret)) {
             $client = $oauth2Model->getClientModel()->getClientById($inputClientId);
             if (!empty($client) and !$oauth2Model->getClientModel()->verifySecret($client, $inputClientSecret)) {
                 throw $this->getNoPermissionResponseException();
             }
         }
     } else {
         $client = $oauth2Model->getClientModel()->getClientById($oauthClientId);
     }
     if (empty($client)) {
         throw $this->getNoPermissionResponseException();
     }
     return $client;
 }
Beispiel #10
0
 public function isValidTopic(&$topic, array $viewingUser = null)
 {
     $this->standardizeViewingUserReference($viewingUser);
     list($type, $id) = self::parseTopic($topic);
     if ($type != self::TYPE_CLIENT && !bdApi_Option::getSubscription($type)) {
         // subscription for this topic type has been disabled
         return false;
     }
     switch ($type) {
         case self::TYPE_NOTIFICATION:
             if ($id === 'me') {
                 // now supports user_notification_me
                 $id = $viewingUser['user_id'];
                 $topic = self::getTopic($type, $id);
             }
             return $id > 0 and $id == $viewingUser['user_id'];
         case self::TYPE_THREAD_POST:
             /* @var $threadModel XenForo_Model_Thread */
             $threadModel = $this->getModelFromCache('XenForo_Model_Thread');
             $thread = $threadModel->getThreadById($id);
             return $thread['user_id'] == $viewingUser['user_id'];
         case self::TYPE_USER:
             if ($id === 'me') {
                 // now supports user_me
                 $id = $viewingUser['user_id'];
                 $topic = self::getTopic($type, $id);
             }
             return $id > 0 and $id == $viewingUser['user_id'];
         case self::TYPE_CLIENT:
             $session = bdApi_Data_Helper_Core::safeGetSession();
             return $session->getOAuthClientId() !== '';
     }
     return false;
 }