source: Dev/branches/jos-branch/server/classes/models/Session.php @ 285

Last change on this file since 285 was 285, checked in by jkraaijeveld, 13 years ago

Merge from rest-dojo-ui 272-282

File size: 10.3 KB
Line 
1<?php
2require_once 'rdfConstants.php';
3// Include RAP Library to write RDF files
4include(RDFAPI_INCLUDE_DIR . "RDFAPI.php");
5/**
6 * Description of Session
7 *
8 * @author jkraaijeveld
9 */
10
11class Session extends ResearchToolObject
12{
13        private static $filename = 'data/sessions/sessions.rdf';
14
15        public $title;
16        public $creator;
17        public $creationdate;
18        public $pipeline;
19
20       
21        /**
22         * Constructor for a Session object
23         * @param type $uid
24         * @param type $title
25         * @param type $creator
26         * @param type $creationdate
27         * @param type $pipeline
28         */
29        public function __construct($uid = null, $title = null, $creator = null, $creationdate = null, $pipeline = null)
30        {
31                if(!isset($uid))
32                {
33                        $uid = md5(uniqid(rand(), true));
34                }
35                $this->uid = $uid;
36                $this->title = $title;
37                $this->creator = $creator;
38                $this->creationdate = $creationdate;
39                $this->pipeline = $pipeline;
40        }
41
42        /*
43         * function evaluate(()
44         * Evaluates all the references of this object.
45         */
46        public function evaluate()
47        {
48                if(is_string($this->creator))
49                {
50                        $result = User::get(array("uid" => $this->creator));
51                        if(!isset($result[0]))
52                                return false;
53                        $this->creator = $result[0];
54                }
55                if(!empty($this->pipeline) && is_string($this->pipeline[0]))
56                {
57                        $newPipeline = array();
58                        foreach($this->pipeline as $element)
59                        {
60                                //Check if the element's UID can be found in surveys, if not:
61                                //Check applications. If it isn't in either: invalid reference.
62                                $result = Survey::get(array("uid" => $element));
63                                if(!isset($result[0]))
64                                        $result = Application::get(array("uid" => $element));
65                                if(!isset($result[0]))
66                                        return false;
67                                $newPipeline[] = $result[0];
68                        }
69                        $this->pipeline = $newPipeline;
70                }
71                return true;
72        }
73
74        /**
75         * function save()
76         * Saves the current object into the database.
77         */
78        public function save()
79        {
80                //If evaluation fails, some references are incorrect.
81                //We shouldn't save in this case. Instead - let the user know. This function returns false if the evaluation has failed.
82                //TODO: Decide how to fix invalid references graciously.
83                if(!$this->evaluate())
84                        throw new Exception('Evaluation failed.');
85
86                //Ensure the required folder exists.
87                if(!is_dir('data/sessions/'))
88                        mkdir('data/sessions/');
89
90                $model = ResearchToolObject::load(Session::$filename);
91
92                $resourceSession = new Resource(SESSION . '/' . $this->uid);
93                //Remove the old value stored with the given id
94                $model->subtract($model->find($resourceSession, null, null));
95
96                //Set the new values
97                $resourceSessionType = new Resource(SESSION);
98                $predicateType = new Resource(RTYPE);
99                $model->add(new Statement($resourceSession, $predicateType, $resourceSessionType));
100
101                $sessionId = new Literal($this->uid);
102                $predicateId = new Resource(UID);
103                $model->add(new Statement($resourceSession, $predicateId, $sessionId));
104
105                $sessionTitle = new Literal($this->title);
106                $predicateTitle = new Resource(TITLE);
107                $model->add(new Statement($resourceSession, $predicateTitle, $sessionTitle));
108
109                $sessionCreator = new Literal($this->creator->uid);
110                $predicateCreator = new Resource(CREATOR);
111                $model->add(new Statement($resourceSession, $predicateCreator, $sessionCreator));
112
113                $sessionTimestamp = new Literal($this->creationdate->getTimestamp());
114        //      $sessionTimestamp = new Literal($this->datetime);    // Edit of above function, allows for creation of session, but still results in errors...
115        $predicateTimestamp = new Resource(CREATIONDATE);
116                $model->add(new Statement($resourceSession, $predicateTimestamp, $sessionTimestamp));
117
118                //Create a sequence to store the different applications and surveys.
119                if(isset($this->pipeline))
120                {
121                        foreach($this->pipeline as $element)
122                        {
123                                $sessionObject = new Literal($element->uid);
124                                $predicateObject = null;
125                                if(get_class($element) == "Application")
126                                        $predicateObject = new Resource(HAS_APPLICATION);
127                                else if(get_class($element) == "Survey")
128                                        $predicateObject = new Resource(HAS_SURVEY);
129                                if(isset($predicateObject))
130                                        $model->add(new Statement($resourceSession, $predicateObject, $sessionObject));
131                        }
132                }
133
134                if(isset($this->answersets))
135                {
136                        foreach($this->answersets as $answerset)
137                        {
138                                $sessionAnswerSet = new Literal($answerset->uid);
139                                $predicateAnswerSet = new Resource(HAS_ANSWERSET);
140                                $model->add(new Statement($resourceSession, $predicateAnswerSet, $sessionAnswerSet));
141                        }
142                }
143               
144                return $model->saveAs(Session::$filename, 'rdf');
145        }
146
147
148        /**
149         * function get()
150         * @param type $arguments : An array containing one or more of the following elements:
151         * 'uid', 'title', 'creationdate', 'applications', 'surveys'
152         */
153        public static function get($arguments)
154        {
155                $model = ResearchToolObject::load(Session::$filename);
156       
157                //Build the query string
158                $querystring = '
159                        PREFIX predicates: <' . SURVEYTOOL_PREDICATES_NAMESPACE . '>
160                        PREFIX resources: <' . SURVEYTOOL_RESOURCES_NAMESPACE . '>
161                        SELECT DISTINCT ?uid, ?title, ?creator, ?creationdate
162                        WHERE
163                        {
164                                _session predicates:resource_type resources:session ;
165                                predicates:uid ?uid ;
166                                predicates:title ?title ;
167                                predicates:creator ?creator ;
168                                predicates:creationdate ?creationdate ;
169                                ' . ResearchToolObject::createArguments($arguments) . '
170                        }';
171                //Query the model
172                $results = $model->sparqlQuery($querystring);
173                $sessions = array();
174                if(!empty($results))
175                {
176                        foreach($results as $result)
177                        {
178                                //Create a session object out of every result, get all required fields as well.
179                                $pipeline = Session::getPipeline($model, $result['?uid']->label);
180                                $creator = $result['?creator']->label;
181                                $creationdate = new DateTime();
182                                $creationdate->setTimestamp(intval($result['?creationdate']->label));
183                                $sessions[] = new Session($result['?uid']->label, $result['?title']->label, $creator, $creationdate, $pipeline);
184                        }
185                }
186                return $sessions;
187        }
188        /**
189         * function getPipeline()
190         * param type $uid : The Session uid for which the pipeline should be retrieved.
191         */
192        private static function getPipeline($model, $uid)
193        {
194                $result = $model->findRegex("[(".$uid.")]", "[(has_application)|(has_survey)]" ,null);
195                $iterator = $result->getStatementIterator();
196                $pipeline = array();
197                while($iterator->hasNext())
198                {
199                        $element = $iterator->next();
200                        $pipeline[] = $element->getLabelObject();
201                }
202                return $pipeline;
203        }
204
205        /**
206         * function toSPSS
207         * @param type $location
208         * Writes an SPSS parseable file at the given location, named '$datetime_$title.txt'
209         * One big note about toSPSS: If this session contains multiple instances of THE SAME Survey,
210         * the world burns, people die, etcetera. (or, in a more fortunate case, the latest values
211         * are written to the file whilst the others get lost.
212         */
213        //DO NOT USE - BROKEN AS OF 23/12/2011
214        public function toSPSS($location)
215        {
216                $this->evaluate();
217                if(!is_dir($location))
218                {
219                        mkdir($location);
220                }
221                //Create the filename, open the file at the given location
222                $fileName = $this->datetime->format("d-m-Y") . "_" . $this->title . ".txt";
223
224                //Make a list of all 'column headers', e.g. "respondent" and all the question codes.
225                $headers = array();
226                $headers[] = "respondent";
227                foreach ($this->pipeline as $element)
228                {
229                        if(get_class($element) == "Survey")
230                        {
231                                $element->evaluate();
232                                foreach($element->questions as $question)
233                                {
234                                        //TODO: This might need fixing after lazy initialization refactoring.
235                                        $headers[] = $element->title . '_' . $question->uid;
236                                }
237                        }
238                }
239                //Return if there are no surveys.
240                if(count($headers) < 2)
241                        return;
242               
243                //Get the answers for all respondents
244                $answers = $this->getAnswers($headers);
245
246                //Create the strings and write to file.
247                $headerString = "";
248                foreach($headers as $headerElement)
249                {
250                        $headerString = $headerString . $headerElement . "\t";
251                }
252                $fileHandler = fopen($location . '/' . $fileName, 'w') or die("File in use");
253                fwrite($fileHandler, $headerString . "\n");
254                foreach($answers as $entry)
255                {
256                        $entryString = "";
257                        //PHP doesn't automatically sort the indices so I have to do it myself
258                        //Entry elements can now be printed in order to match the headers
259                        for ($i = 0; $i < count($headers); $i++)
260                        {
261                                if(in_array($i, array_keys($entry)))
262                                        $entryString = $entryString . $entry[$i] . "\t";       
263                                else
264                                        $entryString = $entryString . "\t";
265                        }
266                        fwrite($fileHandler, $entryString . "\n");     
267                }
268        }
269
270        /*
271         * function getAnswers
272         * @param type $headers
273         * Based on the questions specified in the headers array, matches the answers of every
274         * respondent to the correct questions and returns an array containing a list of answers per
275         * respondent
276         */
277        private function getAnswers($headers)
278        {
279                //Add the answers per survey per respondent. Requires some extra looping to assure proper ordering.
280                //Keeps a list of respondents which have already been used. If an answerset exists for a respondent which
281                //already exists within the answers-array, use the index of the respondent. Else: make a new row.
282                $respondentsUsed = array();
283                $answers = array();
284                foreach($this->answersets as $answerset)
285                {
286                        $entryIndex;
287                        if(in_array($answerset->respondent->name, $respondentsUsed))
288                        {
289                                $entryIndex = array_search($answerset->respondent->name, $respondentsUsed);
290                                $entry = $answers[$entryIndex];
291                        }
292                        else
293                        {
294                                $entry = array();
295                                $entry[0] = $answerset->respondent->name;
296                                $entryIndex = count($respondentsUsed);
297                                $respondentsUsed[] = $answerset->respondent->name;
298                        }
299                        foreach ($answerset->answers as $answer)
300                        {
301                                $index = array_search($answerset->survey->title . '_' . $answer->question->uid, $headers);
302                                //Index has to be a good number, else the answer doesn't belong in this session
303                                //Causes might be a missing question or having a wrong survey
304                                if($index != 0)
305                                {
306                                        $value = "";
307                                        foreach ($answer->values as $val)
308                                        {
309                                                $value = $value . $val . ",";
310                                        }
311                                        //We all hate trailing commas
312                                        if (strlen($value) > 0) { $value = substr($value, 0, strlen($value)-1); }
313                                        $entry[$index] = $value;
314                                }
315                        }
316                        $answers[$entryIndex] = $entry;
317                }
318                return $answers;
319        }
320
321    public static function create($obj) {
322        return new Session($obj->uid, $obj->title, $obj->creator,
323                $obj->creationdate, $obj->pipeline);
324    }
325
326}       
327
328?>
Note: See TracBrowser for help on using the repository browser.