Skip to content

Instantly share code, notes, and snippets.

@richlove1
Created April 20, 2012 15:16
Show Gist options
  • Save richlove1/2429539 to your computer and use it in GitHub Desktop.
Save richlove1/2429539 to your computer and use it in GitHub Desktop.
<?php
/**
* @version SocialLearn 2.0
* @author Richard Greenwood <r.m.greenwood@open.ac.uk>
* @copyright Copyright (c) 2011-2012, The Open University
* @licence http://opensource.org/licenses/gpl-license.php GNU Public License
*/
namespace App\Service;
/**
* @package service
* @subpackage recommendation
*/
class Recommendation extends Base {
public function __construct() {
}
public function getUserRecs($userId, $shown = 0, $followed = 0){
try {
$db = \Zend_Registry::get('db');
$dbConnection = $db->getDBConnection();
$sql = <<<EOF
SELECT *
FROM sl_rec_user_recommendations
WHERE user_id = %i
AND user_shown = %i
AND user_followed = %i
EOF;
$recs_followed = $dbConnection->query($sql, $userId, $shown, $followed);
$result = array();
foreach ($recs_followed as $value) {
$result[] = $value['ent_id'];
}
return $result;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return 0;
}
}
public function createUserRecommendation($userId, $entityId, $seedTypeId, $seedId, $relScore, $qualityScore){
try {
try {
$userRecObject = \fRecordSet::buildFromSQL(
'App_Entity_RecUserRecommendation', array('SELECT *
FROM sl_rec_user_recommendations
WHERE user_id = %i
AND ent_id = %i', $userId, $entityId)
);
foreach ($userRecObject->getRecords() as $record) {
//If the relevance score of the existing entity is lower than we're trying to save, update it with the new score
if ($record->getRelScore() < $relScore) {
$record->setSeedTypeId($seedTypeId);
$record->setSeedId($seedId);
$record->setRelScore($relScore);
$record->setQualityScore($qualityScore);
$record->store();
}
//If the relevance is the same but the quality score of the existing entity is lower than we're trying to save, update it with the new score
elseif ($record->getRelScore() == $relScore && $record->getQualityScore() < $qualityScore) {
$record->setSeedTypeId($seedTypeId);
$record->setSeedId($seedId);
$record->setRelScore($relScore);
$record->setQualityScore($qualityScore);
$record->store();
}
}
} catch (\Exception $e) {
$userRecObject = new \App_Entity_RecUserRecommendation();
$userRecObject->setUserId($userId);
$userRecObject->setEntId($entityId);
$userRecObject->setSeedTypeId($seedTypeId);
$userRecObject->setSeedId($seedId);
$userRecObject->setRelScore($relScore);
$userRecObject->setQualityScore($qualityScore);
$userRecObject->store();
}
return $userRecObject;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return false;
}
}
public function updateUserRecShown($userId, $entityId) {
try {
$userRecObject = \fRecordSet::buildFromSQL(
'App_Entity_RecUserRecommendation', array('SELECT *
FROM sl_rec_user_recommendations
WHERE user_id = %i
AND ent_id = %i', $userId, $entityId)
);
foreach ($userRecObject->getRecords() as $record) {
$record->setUserShown(1);
$record->store();
}
return $userRecObject;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return false;
}
}
public function updateUserRecFollowed($userId, $entityId) {
try {
$userRecObject = \fRecordSet::buildFromSQL(
'App_Entity_RecUserRecommendation', array('SELECT *
FROM sl_rec_user_recommendations
WHERE user_id = %i
AND ent_id = %i', $userId, $entityId)
);
foreach ($userRecObject->getRecords() as $record) {
$record->setUserFollowed(1);
$record->store();
}
return $userRecObject;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return false;
}
}
public function getUserTagFeed($userId, $interestLevel = null){
try {
$db = \Zend_Registry::get('db');
$dbConnection = $db->getDBConnection();
switch ($interestLevel) {
case 'confirmed':
$interestLevelSql = ' AND interest_level = 1 ';
break;
case 'rejected':
$interestLevelSql = ' AND interest_level = -1 ';
break;
case 'unknown':
$interestLevelSql = ' AND interest_level = 0 ';
break;
default:
$interestLevelSql = '';
}
$sql = <<<EOF
SELECT *
FROM sl_rec_user_tag_feed utf
INNER JOIN sl_tags t ON t.tag_id = utf.tag_id
WHERE user_id = %i $interestLevelSql
ORDER BY interest_level DESC
EOF;
$user_tags = $dbConnection->query($sql, $userId);
$result = array();
foreach ($user_tags as $value) {
$result[] = (object) array(
'tag_id' => $value['tag_id'],
'tag_desc' => $value['tag_desc'],
'interest_level' => $value['interest_level'],
'tag_source_id' => $value['tag_source_id']
);
}
return $result;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return 0;
}
}
//Use to insert a completely new user tag feed record with chosen surface weighting
public function createUserTagFeed($userId, $tagIdsArray, $interestLevel = 0, $surfaceWeighting, $predicate, $entityId){
try {
$predicateId = \App_Entity_Predicate::getPredicateId($predicate);
foreach($tagIdsArray as $tagId) {
try {
//Try and retreive a user tag feed record for the user and tag
$userTagObjects = \fRecordSet::buildFromSQL(
'App_Entity_RecUserTagFeed', array('SELECT *
FROM sl_rec_user_tag_feed
WHERE user_id = %i
AND tag_id = %i', $userId, $tagId)
);
//If we have an unconfirmed user tag feed record and surface weighting is less than what we're asking to set it to the new higher value
if($userTagObjects[0]->getUserId()) {
$userTagObject = $userTagObjects[0];
if ($userTagObject->getInterestLevel() == 0 && $userTagObject->getSurfaceWeighting() < $surfaceWeighting) {
$userTagObject->setSurfaceWeighting($surfaceWeighting);
$userTagObject->setPredicateId($predicateId);
$userTagObject->setEntityId($entityId);
$userTagObject->store();
}
}
} catch (\Exception $e) {
//We don't have a user tag feed record so create one
$userTagObject = new \App_Entity_RecUserTagFeed();
$userTagObject->setUserId($userId);
$userTagObject->setTagId($tagId);
$userTagObject->setInterestLevel($interestLevel);
$userTagObject->setSurfaceWeighting($surfaceWeighting);
$userTagObject->setPredicateId($predicateId);
$userTagObject->setEntityId($entityId);
$userTagObject->store();
}
}
return true;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return false;
}
}
public function updateUserTagInterest($userId, $tagId, $interestLevel) {
try {
$userTagObject = \fRecordSet::buildFromSQL(
'App_Entity_RecUserTagFeed', array('SELECT *
FROM sl_rec_user_tag_feed
WHERE user_id = %i
AND tag_id = %i', $userId, $tagId)
);
foreach ($userTagObject->getRecords() as $record) {
$record->setInterestLevel($interestLevel);
//RichLove: Have commented this out as we've decided to leave the surface weighting as it is
//even if the user confirmed or rejected a tag
//$record->setSurfaceWeighting(0);
$record->store();
}
return $userTagObject;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return false;
}
}
public function getEntityDerivedTags($entityId = null){
try {
$db = \Zend_Registry::get('db');
$dbConnection = $db->getDBConnection();
$entitySql = (is_numeric($entityId) ? ' AND tag_subject_entity_id = ' .$entityId : '');
$sql = <<<EOF
SELECT *
FROM sl_rec_entity_derived_tags edr
INNER JOIN sl_tags t on t.tag_id = edr.tag_tag_id
WHERE 1=1 $entitySql
EOF;
$entityDerivedTags= $dbConnection->query($sql);
$result = array();
foreach ($entityDerivedTags as $value) {
$result[] = (object) array(
'entity_id' => $value['tag_subject_entity_id'],
'tag_id' => $value['tag_tag_id'],
'tag_desc' => $value['tag_desc']
);
}
return $result;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return 0;
}
}
public function getRecsToProcess(){
try {
$recsToProcess = \fRecordSet::buildFromSQL(
'App_Entity_RecProcess',
array(' SELECT *
FROM sl_rec_process
WHERE needs_processing = %i',
1
)
);
$result = array();
foreach ($recsToProcess as $row) {
$result[] = $row->getProcessId();
}
return $result;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return 0;
}
}
public function updateRecProcessState($processState = 1, $entityIds){
try {
$recsToProcess = \fRecordSet::buildFromSQL(
'App_Entity_RecProcess',
array(' SELECT *
FROM sl_rec_process
WHERE entity_id in (' .$entityIds .')',
)
);
foreach ($recsToProcess->getRecords() as $record) {
$record->setNeedsProcessing($processState);
$record->store();
}
return $recsToProcess;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return 0;
}
}
public function updateRecProcess($userId,$entityId,$needsProcessing = 0){
try {
$recToProcess = \fRecordSet::buildFromSQL(
'App_Entity_RecProcess',
array(' SELECT *
FROM sl_rec_process
WHERE user_id = %i
AND entity_id = %i', $userId, $entityId
)
);
//If a process record already exists
if (count($recToProcess->getRecords())) {
foreach ($recToProcess->getRecords() as $record) {
$viewCount = $record->getEntityViewCount();
if (++$viewCount >= 5) {
$needsProcessing = 1;
};
$record->setEntityViewCount($viewCount);
if ($needsProcessing) {
$record->setNeedsProcessing($needsProcessing);
}
$record->store();
}
}
//Add a new record to process
else {
$sequenceRecProcess= new \App_Entity_SequenceRecprocess();
$processId = $sequenceRecProcess->getSequence();
$recToProcess = new \App_Entity_RecProcess();
$recToProcess->setProcessId($processId);
$recToProcess->setUserId($userId);
$recToProcess->setEntityId($entityId);
$recToProcess->setEntityViewCount(1);
$recToProcess->setNeedsProcessing($needsProcessing);
$recToProcess->store();
}
return $recToProcess;
} catch (\Exception $e) {
$this->_addToErrorStack($e);
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment