source: Dev/branches/rest-dojo-ui/server/classes/models/Session.php @ 302

Last change on this file since 302 was 302, checked in by hendrikvanantwerpen, 13 years ago

Merge jos-branch 285:298

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