diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 2cc9d16..91c1204 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -1,21 +1,4 @@ id)->assignments()->with('feature')->get(); + $assignments = User::find(Auth::user()->id)->assignments()->with('feature')->orderBy('created_at','desc')->get(); $features_all = Feature::all(); $features = new \stdClass(); diff --git a/app/Http/Controllers/DocumentController.php b/app/Http/Controllers/DocumentController.php index 5f4863e..29fe744 100644 --- a/app/Http/Controllers/DocumentController.php +++ b/app/Http/Controllers/DocumentController.php @@ -1,19 +1,4 @@ middleware('auth'); $this->client = new Client($this->graphQLURL); - $this->stringTokeniser = new StringTokenizer(); + // $this->stringTokeniser = new StringTokenizer(); + $this->analyser = new Analyser(); $this->graphQLURL = env('TAP_API', ''). "/graphql"; } @@ -52,6 +77,7 @@ public function generateFeedback(Request $request) { $activityLog->status = 'success'; $activityLog->data =[]; $user_id = Auth::user()->id; + $result = new \stdClass(); if($request['action'] == 'quick') { //single sentence change analysis @@ -62,7 +88,7 @@ public function generateFeedback(Request $request) { $data = array(); $data['txt'] = $request['txt']; $data['grammar'] = $request['extra']['grammar']; - $temp = $this->stringTokeniser->quickTapMoves($data); + $temp = $this->analyser->quickTapMoves($data); $tt['str']= $temp->str ? $temp->str : ''; $tt['raw_tags'] = $temp->raw_tags? $temp->raw_tags : array(); $tt['tags'] = $temp->tags? $temp->tags:''; @@ -74,13 +100,14 @@ public function generateFeedback(Request $request) { } */ else if($request['action'] == 'fetch') { Log::info('moves',['execute time : ' =>'started'.date('d/m/y:H:i:s') ]); - $tap = $this->stringTokeniser->preProcess($request); + $tap = $this->analyser->preProcess($request); + $result->tap = $tap; Log::info('tokeniser',['tokeniser' =>'completed'.date('d/m/y:H:i:s') ]); } - $result = new \stdClass(); + $extra = $request["extra"]; $result->status = array('message' => 'Success', 'code' => 200 ); $result->rules = array(); @@ -221,365 +248,10 @@ protected function getFeedbackSchema($path, $id) } - - protected function background($tap, $rule) { - $result = array(); - $check = $rule['check']; - $tempo = 0; - - foreach($tap as $key => $data) { - $setFeed = new \stdClass(); - $setFeed->str = $data->str; - $setFeed->message = array(); - $setFeed->css = array(); - if ($key < $check['paragraph'] && count($data->raw_tags) > 0) { - if (in_array($check['paragraph'], $data->raw_tags)) { - $tempo++; - } - } - } - - if ($tempo == 0 && $key == $this->para - 1) { - $setFeed->message['background'] = $rule['message']; - $setFeed->css[] = 'background'; - $result[] = $setFeed; - } - - return $result; - } - - protected function metrics($tap, $rule) { - $result = array(); - $check = $rule['check']; - - foreach($tap as $key => $data) { - $tempStore = new \stdClass(); - $tempStore->str = $data->str; - $tempStore->message = array(); - $tempStore->css = array(); - $returnData = $this->stringTokeniser->metrics($data->str); - if(isset($returnData->sentWordCounts)) { - //sentWordCounts is always an array e.g. [5,6] if two sentences sent here we send only one at a time though - if($returnData->sentWordCounts[0] > $check['sentenceWordCount']) { - //$tempStore->message = $rule['message']; - foreach($rule['message'] as $msg) { - if(isset($msg['metrics'])) { - $tempStore->message['metrics'] = $msg['metrics']; - array_push($tempStore->css, 'metrics'); - } - } - } - } - $result[] = $tempStore; - } - return $result; - - } - - - /* - * function works on the complete text at once, so input is not tokenised - * so str = append all tokenised tap outputs into one - */ - - protected function vocab($tap, $rule) { - $result = array(); - $check = $rule['check']; - $termCount = 0; - $words = $check['words']; - $completeText = ""; - - foreach($tap as $key => $data) { - $completeText .= $data->str; - } - $tempStore = new \stdClass(); - $tempStore->str = $completeText; - $tempStore->message = array(); - $tempStore->css =array(); - - $returnData = $this->stringTokeniser->vocab($tempStore->str); - if(isset($returnData->terms)) { - $collection = collect($returnData->terms); - - foreach($check['words'] as $word) { - $filtered= $collection->where('term', $word); - if(count($filtered->all()) == 0) $termCount++; - } - - if($termCount > 0 ) { - foreach($rule['message'] as $msg) { - if(isset($msg['metrics'])) { - $tempStore->message['vocab'] = $msg['vocab']; - $tempStore->css[] = 'vocab'; - } - } - $result[] = $tempStore; - } - } - - return $result; - } - - /* - * *** applicable only for reflective feedback - */ - - protected function expression($tap, $rule) { - $result = array(); - $check = $rule['check']; - $termCount = 0; - $all = $check['all']; - - - if(count($all) == 0) { - return $result; - } - - - foreach($tap as $key => $data) { - $tempStore = new \stdClass(); - $tempStore->str = $data->str; - $tempStore->message = array(); - $tempStore->affect=array(); - $tempStore->epistemic=array(); - $tempStore->modal=array(); - $tempStore->css = array(); - - $returnData = $this->stringTokeniser->expression($data->str); - //$returnData is an array but since we are analysing tokenised strings we can safetly assume array[0] - $sanitizedResult = $returnData[0]; - //$tempStore->raw = $sanitizedResult; - foreach($all as $exp) { - - if (isset($sanitizedResult->{$exp}) && count($sanitizedResult->{$exp}) > 0) { - $tempStore->{$exp} = $sanitizedResult->{$exp}; - foreach($rule['message'] as $msg) { - if(isset($msg[$exp])) { - $tempStore->message[$exp] = $msg[$exp]; - array_push($tempStore->css, $exp); - } - } - } - } - - $result[] = $tempStore; - } - - - return $result; - - } - - - protected function moves($tap, $rule) { - - $result = array(); - $check = $rule['check']; - $tempo = 0; - $tags = $check['tags']; - $messages = $rule['message']; - if(count($tags) == 0) { - return $result; - } - - foreach($tap as $key => $data) { - $setFeed = new \stdClass(); - $setFeed->str = $data->str; - $setFeed->message = array(); - $setFeed->css = array(); - - foreach($tags as $tag) { - if(count(preg_grep("[^".$tag."]", $data->raw_tags)) > 0) { - foreach($messages as $msg) { - if(isset($msg[$tag])) { - $setFeed->message[$tag] = $msg[$tag]; - array_push($setFeed->css,$tag); - } - } - } - } - $result[] = $setFeed; - } - - return $result; - } - - /** - * -- crafted this to cover sophies CARS rules, all the rules guided by features - * @param $tap - all tags per specified calls - * @param $rule - fulled from selected feature - * @return array - returns missing tags - * moves1, move2, move3 precedence orders and messages if not followed + * applicable only for reflective feedback */ - protected function enforced($tap, $rule) { - $result = array(); - $check = $rule['check']; - $tempo = 0; - $tags = $check['tags']; - $messages = $rule['message']; - if(count($tags) == 0) { - return $result; - } - $monitor = array(); - $issues = array(); - - if($rule["tabEval"] === 'dynamic') { - - - foreach ($tap as $key => $data) { - $setFeed = new \stdClass(); - $setFeed->str = $data->str; - $setFeed->message = array(); - $setFeed->css = array(); - $setFeed->interim = array(); - - $temp = array(); - foreach ($tags as $it => $case) { - foreach ($case as $k => $tag) { - if (count(array_intersect($tag, $data->raw_tags)) > 0) { - $temp[] = $k; - } - } - } - - if (count($temp) > 0) { - arsort($temp); - $sorted = array_unique($temp); - // print_r(current($sorted)); - array_push($monitor, current($sorted)); - } - } - - foreach ($monitor as $key => $d) { - if (isset($monitor[$key + 1])) { - $pre = $monitor[$key]; - $next = $monitor[$key + 1]; - $idx = $pre.$next; - if ($pre > $next) { - foreach ($messages as $msg) { - if (isset($msg['problem' . $idx])) array_push($issues, $msg['problem' . $idx]); - } - } - } - } - - // print_r($issues); - - //check for missing moves - $unique_moves = array_unique($monitor); - //print_r($unique_moves); - foreach (array(1, 2, 3) as $move) { - if (!in_array($move, $unique_moves)) { - foreach ($messages as $msg) { - if (isset($msg['missing' . $move])) array_push($issues, $msg['missing' . $move]); - } - } - } - - - } else { - foreach($messages as $key => $msg) { - array_push($issues, $msg); - } - } - - array_push($result, $issues); - //print_r($result); - return $result; - } - - protected function missingTags($tap, $rule) { - $result = array(); - $check = $rule['check']; - $tempo = 0; - $tags = $check['tags']; - $messages = $rule['message']; - if(count($tags) == 0) { - return $result; - } - $monitor = array(); - $issues = array(); - - if($rule["tabEval"] === 'dynamic') { - - $temp = array(); - foreach ($tap as $key => $data) { - $temp = array_merge($temp, $data->raw_tags); - } - - $temp = array(); - $temp_temp =array(); - foreach ($tap as $key => $data) { - $temp_temp = array_merge($temp_temp, $data->raw_tags); - } - - /*** - * hacky stuff that violates the flow of rules - for Shibani.... - * if contrast and question present don't add error - * else if neither of them present show error - * solution replace all contrast tags with question and check for question(nostat) - * if present don't error else error!!!! - ***/ - - foreach($temp_temp as $v) { - if($v=='contrast') { array_push($temp, 'nostat');} - else { array_push($temp, $v); } - } - - $monitor = array_unique($temp); - - foreach ($tags as $d) { - if (!in_array($d, $monitor)) { - foreach ($messages as $msg) { - if (isset($msg[$d])) array_push($issues, $msg[$d]); - } - } - } - - - } else { - foreach($messages as $key => $msg) { - array_push($issues, $msg); - } - } - - array_push($result, $issues); - //print_r($result); - return $result; - } - - - - - - - - - protected function staticFeed($tap, $rule) { - $result = array(); - $check = $rule['check']; - $tempo = 0; - $tags = $check['tags']; - $messages = $rule['message']; - - $monitor = array(); - $issues = array(); - - if($rule["tabEval"] === 'dynamic') { - - } else { - foreach($messages as $key => $msg) { - array_push($issues, $msg['txt']); - } - } - array_push($result, $issues); - return $result; - } - - - protected function formatFeedback($tap, $result) { $final = array(); @@ -609,8 +281,6 @@ protected function formatFeedback($tap, $result) { return $final; - - } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 645d26d..1e7b45c 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -1,19 +1,4 @@ 150]); + public function __construct() + { + $this->checks = new \stdClass(); + $this->checks->reflective = new \stdClass(); + $this->checks->analytical = new \stdClass(); + + //reflective def's + $this->checks->reflective->icons = array( + "context", + "challenge", + "change", + "metrics" + ); + + //affect tag validity criteria + $this->checks->reflective->affect_validity = array( + "context", + "challenge", + "change" + ); + + //inline text replacement tags + $this->checks->reflective->inlineTxt = array( + "affect" => "affect", + "epistemic" => "epistemic", + "modal" => "modall" + ); + + //analytical defs + $this->checks->analytical->analytic_xlator = array( + "metrics" => "metrics", + "emph" => "E", + "grow" => "T", + "contrast" => "C", + "contribution" => "S", + "nostat" => "Q", + "tempstat" => "B", + "novstat"=> "N", + "surprise"=>"S", + "attitude"=> "P" + ); + $this->checks->analytical->moves_css = array( + "moves1", + "moves2", + "moves3" + ); + } + + public function pdfview ($ref= NULL) { + PDF::setOptions(['dpi' => 96, 'defaultFont' => 'arial']); + if($ref) { - $draft = Draft::where('id',$ref)->get(); + $encoded_data = json_decode($ref); + $document_id = $encoded_data->id/123456; //document Id + $id = Draft::where('document_id', $document_id)->get()->max('id'); + + if(!$id) { + return redirect()->back()->with('error', 'This document does not have any feedback associated with it.'); + } + + $draft = Draft::where('id',$id)->get(); $draft[0]->raw = json_decode($draft[0]->raw_response); - // dd($draft[0]->raw); - view()->share('draft', $draft[0]); - $pdf = PDF::loadView('pdf.view'); + // dd($draft[0]->raw); + $pdfOut = new \stdClass(); + $pdfOut->raw = $draft[0]->raw; + $pdfOut->annotated = $this->getAnnotation($draft[0]->raw, $encoded_data->grammar); + $pdfOut->name = $encoded_data->name; + $pdfOut->grammar = strtoupper($encoded_data->grammar); + $pdfOut->original = $draft[0]->text_input; + $pdfOut->created_at = $draft[0]->created_at; + + //dd($pdfOut); + view()->share('draft', $pdfOut); + if($encoded_data->grammar =='analytical') { + $pdf = PDF::loadView('pdf.analytical'); + } + if($encoded_data->grammar =='reflective') { + $pdf = PDF::loadView('pdf.reflective'); + } return $pdf->download('feedback.pdf'); } else { return redirect()->back()->with('error','Error generating the Pdf, there are no drafts for this document'); } } + + private function getAnnotation($feed, $grammar) { + $txt =''; + + switch ($grammar) { + case 'reflective': + $inlineClass=""; + $inlineText =""; + + foreach($feed->final as $ref) { + $inlineText = $this->fabricateInlineText($ref); + if (count($ref->css) > 0) { + foreach ($ref->css as $style) { + if(in_array($style, $this->checks->reflective->icons)) { + $txt .= ""; + } + $inlineClass = ($style==="link2me") ? "link2me" : ""; + } + } + $txt .= "".$inlineText.""; + } + break; + case 'analytical': + $spanClass =''; + foreach($feed->final as $ann) { + $spanClass = $this->fabricateInlineClass($ann); + if (count($ann->css) > 0) { + foreach ($ann->css as $style) { + $legend = isset($this->checks->analytical->analytic_xlator[$style]) ? $this->checks->analytical->analytic_xlator[$style] : ''; + if (in_array($style, array('contribution'))) $txt .= "".$legend.""; + elseif (in_array($style, array('background', 'metrics'))) $txt .= ""; + else $txt .= "".$legend.""; + } + // $txt .= "" . $ann->str . ""; + } + $txt .= "" . $ann->str . ""; + //dd($txt); + } + break; + } + return $txt; + } + + + private function fabricateInlineText($feed) { + $html = ''; + + if($feed->str != "" && isset($feed->expression)) { + $html = $feed->str; + + foreach($this->checks->reflective->inlineTxt as $key => $value) { + if($key === 'affect' && + count($feed->expression->{$key}) > 0 && + count(array_intersect($this->checks->reflective->affect_validity, $feed->css)) > 0 + ) { + foreach($feed->expression->{$key} as $word) { + $html= str_replace($word->text, "$word->text", $html); + } + } else { + foreach($feed->expression->{$key} as $word) { + $html= str_replace($word->text, "$word->text", $html); + } + } + } + + } + // dd($html); + return $html; + } + + + + private function fabricateInlineClass($feed) { + $name =''; + $css = []; + + if(count($feed->css) == 0 ) { return $name; } + + foreach($feed as $key => $value) { + //loop to check if moves present in the array + if(in_array($key, $this->checks->analytical->moves_css)) { + if( count($feed->{$key}->css) > 0) $css[] = $key; + } + } + + if(in_array('moves3', $css)) { + $name = "moves3"; + } elseif(in_array('moves2', $css)) { + $name = "moves2"; + } elseif(in_array('moves1', $css)) { + $name = "moves1"; + } else { + if(count($feed->css) === 1 && in_array('metrics', $feed->css)) return ''; + elseif(in_array('contribution', $feed->css)) $name = 'ana_bg_green'; + else $name = 'ana_bg_yellow'; + } + + + return $name; + + } + + + } diff --git a/app/Http/Controllers/StringTokenizer.php b/app/Http/Controllers/StringTokenizer.php index f53eeff..2009b01 100644 --- a/app/Http/Controllers/StringTokenizer.php +++ b/app/Http/Controllers/StringTokenizer.php @@ -1,27 +1,11 @@ input = strip_tags($text); $variables->input = $this->cleanText($text); + $params = new \StdClass(); $tags = array(); //get athanor rethmoves - if($grammar == 'analytical') { - $this->gResponse = $this->client->response($this->queryOneA, $variables); - } elseif($grammar == 'reflective') { - $this->gResponse = $this->client->response($this->queryOneR, $variables); + if($grammar == 'reflective') { + $params->grammar = "reflective"; + $variables->parameters = json_encode($params); + $this->gResponse = $this->client->response($this->queryMoves, $variables); + }elseif($grammar == 'analytical') { + $params->grammar = "analytic"; + $variables->parameters = json_encode($params); + $this->gResponse = $this->client->response($this->queryMoves, $variables); + + //$this->gResponse = $this->client->response($this->queryOneA, $variables); } + + //$this->gResponse = $this->client->response($this->queryMoves, $variables); + if ($this->gResponse->hasErrors()) { dd($this->gResponse->errors()); } else { $raw_tags = $this->gResponse->moves->analytics; foreach($raw_tags as $tag) {$tags = $tag;} } + return $tags; } /* @@ -374,26 +400,7 @@ public function vocab($string) { } return $apiResponse; } - /* - * Used retrive expressions - * input: string single sentence - * normally only used for reflective feedback - * output is an array - */ - public function expression($string) { - $apiResponse = new \StdClass(); - $variables = new \stdClass(); - //$variables->input = $this->cleanText($string); - $variables->input = $this->cleanText($string); - //get metrics - $this->gResponse = $this->client->response($this->queryExpressions, $variables); - if ($this->gResponse->hasErrors()) { - $apiResponse = $this->gResponse->errors(); - } else { - $apiResponse = $this->gResponse->expressions->analytics; - } - return $apiResponse; - } + //quick sentence by sentence /* * Used retrive tags @@ -429,17 +436,27 @@ public function quickTapMoves($data) { public function preProcess($data) { $results = array(); - $tokenisedText = $this->tapTokeniser($data); + $alreadyTapped = isset($data['currentFeedback']['tap'])? $data['currentFeedback']['tap']: array(); + $loop = count($alreadyTapped) > 0 ? true : false; + $key =false; if(count($tokenisedText) >0 ) { //now go through each text and analyse foreach($tokenisedText as $txt) { - $responseTxt = new \stdClass; - $responseTxt->str= $txt->original; + $responseTxt = new \stdClass; + $responseTxt->str= $txt->original; + if($loop) { + $key = array_search($responseTxt->str, array_column($alreadyTapped, 'str')); + } + if($key) { + $responseTxt->raw_tags = $alreadyTapped[$key]['raw_tags']; + $responseTxt->tags= $alreadyTapped[$key]['tags']; + } else { $tags = $this->rethoMoves($txt->original, $data['extra']['grammar']); $responseTxt->raw_tags = count($tags)>0 ? $tags : array(); $responseTxt->tags= implode(', ',$tags); - $results[]=$responseTxt; + } + $results[]=$responseTxt; } } @@ -448,9 +465,6 @@ public function preProcess($data) { - - - protected function cleanText($string) { //$pattern = array('/<\/p>/' , '//', '/ /'); //$replace = array('\n', '\n', ''); diff --git a/app/Http/Traits/Analytical/Accounts.php b/app/Http/Traits/Analytical/Accounts.php new file mode 100644 index 0000000..3d2a7ed --- /dev/null +++ b/app/Http/Traits/Analytical/Accounts.php @@ -0,0 +1,230 @@ + $data) { + $setFeed = new \stdClass(); + $setFeed->str = $data->str; + $setFeed->message = array(); + $setFeed->css = array(); + + $temp_tap_raw_tags =array(); + + + $filtered = array(); + foreach($data->raw_tags as $raw) { + if($raw == 'nostat') { + array_push($temp_tap_raw_tags, 'contrast'); + } else { + array_push($temp_tap_raw_tags, $raw); + } + } + + $filtered = array_unique($temp_tap_raw_tags); + + foreach($tags as $tag) { + + if(count(preg_grep("[^".$tag."]", $filtered)) > 0) { + foreach($messages as $msg) { + if(isset($msg[$tag])) { + $setFeed->message[$tag] = $msg[$tag]; + if(!in_array($tag,$setFeed->css)) { + array_push($setFeed->css, $tag); + } + } + } + } + } + + $result[] = $setFeed; + } + + return $result; + } + + /** + * @param $tap + * @param $rule -- used for accounting rules + * @return array + */ + + public function missingSwapTags($tap, $rule) { + $result = array(); + $check = $rule['check']; + $tempo = 0; + $tags = $check['tags']; + $messages = $rule['message']; + $conditions = $check['conditions']; + if(count($tags) == 0) { + return $result; + } + $monitor = array(); + $issues = array(); + + if($rule["tabEval"] === 'dynamic') { + + $temp = array(); + $temp_temp =array(); + foreach ($tap as $key => $data) { + $temp_temp = array_merge($temp_temp, $data->raw_tags); + } + + //print_r($temp_temp); + + foreach($temp_temp as $raw) { + if($raw == 'nostat' || $raw == 'emph') { + if ($raw == 'nostat') { + array_push($temp, 'contrast'); + } + if ($raw == 'emph') { + array_push($temp, 'attitude'); + } + } else { + array_push($temp, $raw); + } + } + + $monitor = array_unique($temp); + //print_r($monitor); + + foreach ($tags as $d) { + if (!in_array($d, $monitor)) { + foreach ($messages as $msg) { + if (isset($msg[$d])) array_push($issues, $msg[$d]); + } + } + } + + //check for any conditional positive feedback - true iff all the tags are added + if(count($conditions) > 0 && count($issues) == 0) { + //will be positive in case of accounts + $cond_value= $conditions[0]; + foreach ($messages as $msg) { + if (isset($msg[$cond_value])) array_push($issues, $msg[$cond_value]); + } + } + + } else { + foreach($messages as $key => $msg) { + array_push($issues, $msg); + } + } + + array_push($result, $issues); + //print_r($result); + return $result; + } + + /** + * will positive feedback per existing tag + * @param $tap + * @param $rule -- used for accounting positive feedback + * @return array + */ + + public function positiveFeed($tap, $rule) { + $result = array(); + $check = $rule['check']; + $tempo = 0; + $tags = $check['tags']; + $messages = $rule['message']; + $conditions = $check['conditions']; + if(count($tags) == 0) { + return $result; + } + $monitor = array(); + $issues = array(); + + if($rule["tabEval"] === 'dynamic') { + + $temp = array(); + $temp_temp =array(); + foreach ($tap as $key => $data) { + $temp_temp = array_merge($temp_temp, $data->raw_tags); + } + + //print_r($temp_temp); + + foreach($temp_temp as $raw) { + if($raw == 'nostat' || $raw == 'emph') { + if ($raw == 'nostat') { + array_push($temp, 'contrast'); + } + if ($raw == 'emph') { + array_push($temp, 'attitude'); + } + } else { + array_push($temp, $raw); + } + } + + $monitor = array_unique($temp); + //print_r($monitor); + $aggregate_tags = array(); + + foreach ($tags as $d) { + if (in_array($d, $monitor)) { + foreach ($messages as $msg) { + if (isset($msg[$d])) array_push($aggregate_tags, $msg[$d]); + } + } + } + if(count($aggregate_tags) >0) { + $issues[] = "
Good job! AcaWriter spotted these key moves: " . implode(',', $aggregate_tags) . "
"; + } + } else { + foreach($messages as $key => $msg) { + array_push($issues, $msg); + } + } + + array_push($result, $issues); + //print_r($result); + return $result; + } + + + + + + +} \ No newline at end of file diff --git a/app/Http/Traits/Analytical/Cars.php b/app/Http/Traits/Analytical/Cars.php new file mode 100644 index 0000000..e5118d4 --- /dev/null +++ b/app/Http/Traits/Analytical/Cars.php @@ -0,0 +1,111 @@ + $data) { + $setFeed = new \stdClass(); + $setFeed->str = $data->str; + $setFeed->message = array(); + $setFeed->css = array(); + $setFeed->interim = array(); + + $temp = array(); + foreach ($tags as $it => $case) { + foreach ($case as $k => $tag) { + if (count(array_intersect($tag, $data->raw_tags)) > 0) { + $temp[] = $k; + } + } + } + + if (count($temp) > 0) { + arsort($temp); + $sorted = array_unique($temp); + // print_r(current($sorted)); + array_push($monitor, current($sorted)); + } + } + + foreach ($monitor as $key => $d) { + if (isset($monitor[$key + 1])) { + $pre = $monitor[$key]; + $next = $monitor[$key + 1]; + $idx = $pre.$next; + if ($pre > $next) { + foreach ($messages as $msg) { + if (isset($msg['problem' . $idx])) array_push($issues, $msg['problem' . $idx]); + } + } + } + } + + // print_r($issues); + + //check for missing moves + $unique_moves = array_unique($monitor); + //print_r($unique_moves); + foreach (array(1, 2, 3) as $move) { + if (!in_array($move, $unique_moves)) { + foreach ($messages as $msg) { + if (isset($msg['missing' . $move])) array_push($issues, $msg['missing' . $move]); + } + } + } + + + } else { + foreach($messages as $key => $msg) { + array_push($issues, $msg); + } + } + + array_push($result, $issues); + //print_r($result); + return $result; + } +} \ No newline at end of file diff --git a/app/Http/Traits/Analytical/Law.php b/app/Http/Traits/Analytical/Law.php new file mode 100644 index 0000000..182f778 --- /dev/null +++ b/app/Http/Traits/Analytical/Law.php @@ -0,0 +1,93 @@ + $data) { + $temp = array_merge($temp, $data->raw_tags); + } + + $temp = array(); + $temp_temp =array(); + foreach ($tap as $key => $data) { + $temp_temp = array_merge($temp_temp, $data->raw_tags); + } + + /*** + * hacky stuff that violates the flow of rules - for Shibani.... + * if contrast and question present don't add error + * else if neither of them present show error + * solution replace all contrast tags with question and check for question(nostat) + * if present don't error else error!!!! + ***/ + + foreach($temp_temp as $v) { + if($v=='contrast') { array_push($temp, 'nostat');} + else { array_push($temp, $v); } + } + + $monitor = array_unique($temp); + + foreach ($tags as $d) { + if (!in_array($d, $monitor)) { + foreach ($messages as $msg) { + if (isset($msg[$d])) array_push($issues, $msg[$d]); + } + } + } + + + } else { + foreach($messages as $key => $msg) { + array_push($issues, $msg); + } + } + + array_push($result, $issues); + //print_r($result); + return $result; + } + +} \ No newline at end of file diff --git a/app/Http/Traits/Profiler.php b/app/Http/Traits/Profiler.php new file mode 100644 index 0000000..0e84a9b --- /dev/null +++ b/app/Http/Traits/Profiler.php @@ -0,0 +1,238 @@ + $data) { + $setFeed = new \stdClass(); + $setFeed->str = $data->str; + $setFeed->message = array(); + $setFeed->css = array(); + + foreach($tags as $tag) { + if(count(preg_grep("[^".$tag."]", $data->raw_tags)) > 0) { + foreach($messages as $msg) { + if(isset($msg[$tag])) { + $setFeed->message[$tag] = $msg[$tag]; + array_push($setFeed->css,$tag); + } + } + } + } + $result[] = $setFeed; + } + + return $result; + } + + /** + * @param $tap + * @param $rule --- added to display static msg into the tab's + * @return array + */ + + public function staticFeed($tap, $rule) { + $result = array(); + $check = $rule['check']; + $tempo = 0; + $tags = $check['tags']; + $messages = $rule['message']; + + $monitor = array(); + $issues = array(); + + if($rule["tabEval"] === 'dynamic') { + + } else { + foreach($messages as $key => $msg) { + array_push($issues, $msg['txt']); + } + } + array_push($result, $issues); + return $result; + } + + public function background($tap, $rule) { + $result = array(); + $check = $rule['check']; + $tempo = 0; + + foreach($tap as $key => $data) { + $setFeed = new \stdClass(); + $setFeed->str = $data->str; + $setFeed->message = array(); + $setFeed->css = array(); + if ($key < $check['paragraph'] && count($data->raw_tags) > 0) { + if (in_array($check['paragraph'], $data->raw_tags)) { + $tempo++; + } + } + } + + if ($tempo == 0 && $key == $this->para - 1) { + $setFeed->message['background'] = $rule['message']; + $setFeed->css[] = 'background'; + $result[] = $setFeed; + } + + return $result; + } + + public function metrics($tap, $rule) { + $analyser = new Analyser(); + $result = array(); + $check = $rule['check']; + + foreach($tap as $key => $data) { + $tempStore = new \stdClass(); + $tempStore->str = $data->str; + $tempStore->message = array(); + $tempStore->css = array(); + $returnData = $analyser->metrics($data->str); + if(isset($returnData->sentWordCounts)) { + //sentWordCounts is always an array e.g. [5,6] if two sentences sent here we send only one at a time though + if($returnData->sentWordCounts[0] > $check['sentenceWordCount']) { + //$tempStore->message = $rule['message']; + foreach($rule['message'] as $msg) { + if(isset($msg['metrics'])) { + $tempStore->message['metrics'] = $msg['metrics']; + array_push($tempStore->css, 'metrics'); + } + } + } + } + $result[] = $tempStore; + } + return $result; + + } + + /** + * function works on the complete text at once, so input is not tokenised + * so str = append all tokenised tap outputs into one + */ + + public function vocab($tap, $rule) { + $analyser = new Analyser(); + $result = array(); + $check = $rule['check']; + $termCount = 0; + $words = $check['words']; + $completeText = ""; + + foreach($tap as $key => $data) { + $completeText .= $data->str; + } + $tempStore = new \stdClass(); + $tempStore->str = $completeText; + $tempStore->message = array(); + $tempStore->css =array(); + + $returnData = $analyser->vocab($tempStore->str); + if(isset($returnData->terms)) { + $collection = collect($returnData->terms); + + foreach($check['words'] as $word) { + $filtered= $collection->where('term', $word); + if(count($filtered->all()) == 0) $termCount++; + } + + if($termCount > 0 ) { + foreach($rule['message'] as $msg) { + if(isset($msg['metrics'])) { + $tempStore->message['vocab'] = $msg['vocab']; + $tempStore->css[] = 'vocab'; + } + } + $result[] = $tempStore; + } + } + + return $result; + } + + /** + * Used retrieve expressions + * input: string single sentence + * normally only used for reflective feedback + * output is an array + */ + + protected function expression($tap, $rule) { + + $analyser = new Analyser(); + $result = array(); + $check = $rule['check']; + $termCount = 0; + $all = $check['all']; + //fetch affect values + $affectValues = $check["affectVal"]? $check["affectVal"] :''; + + if(count($all) == 0) { + return $result; + } + + foreach($tap as $key => $data) { + $tempStore = new \stdClass(); + $tempStore->str = $data->str; + $tempStore->message = array(); + $tempStore->affect=array(); + $tempStore->epistemic=array(); + $tempStore->modal=array(); + $tempStore->css = array(); + + $returnData = $analyser->expression($data->str, $affectValues); + //$returnData is an array but since we are analysing tokenised strings we can safely assume array[0] + $sanitizedResult = $returnData[0]; + //$tempStore->raw = $sanitizedResult; + foreach($all as $exp) { + + if (isset($sanitizedResult->{$exp}) && count($sanitizedResult->{$exp}) > 0) { + $tempStore->{$exp} = $sanitizedResult->{$exp}; + foreach($rule['message'] as $msg) { + if(isset($msg[$exp])) { + $tempStore->message[$exp] = $msg[$exp]; + array_push($tempStore->css, $exp); + } + } + } + } + + $result[] = $tempStore; + } + + return $result; + } +} \ No newline at end of file diff --git a/app/Jobs/StoreDraftWithoutFeedback.php b/app/Jobs/StoreDraftWithoutFeedback.php index 11e7605..8917c3e 100644 --- a/app/Jobs/StoreDraftWithoutFeedback.php +++ b/app/Jobs/StoreDraftWithoutFeedback.php @@ -1,19 +1,4 @@ ref = $draftNew; $activityLog->jobRef = $jobRef; - print_r($activityLog); + //print_r($activityLog); event(new UserActivity($this->user, $activityLog)); diff --git a/app/Jobs/StoreDrafts.php b/app/Jobs/StoreDrafts.php index f258f23..691a084 100644 --- a/app/Jobs/StoreDrafts.php +++ b/app/Jobs/StoreDrafts.php @@ -1,19 +1,4 @@ =5.6.4", "aws/aws-sdk-php-laravel": "~3.0", + "barryvdh/laravel-dompdf": "^0.8.2", + "doctrine/dbal": "^2.6", "euautomation/graphql-client": "^0.2.0", + "barryvdh/laravel-dompdf": "^0.8.2", + "doctrine/dbal": "^2.6", "guzzlehttp/guzzle": "~6.0", "laravel/framework": "5.4.*", "laravel/tinker": "~1.0", @@ -53,6 +57,7 @@ "config": { "preferred-install": "dist", "sort-packages": true, - "optimize-autoloader": true + "optimize-autoloader": true, + "secure-http":false } } diff --git a/database/seeds/FeatureReflectiveUpdateSeeder.php b/database/seeds/FeatureReflectiveUpdateSeeder.php index bfe8ff1..411df3d 100644 --- a/database/seeds/FeatureReflectiveUpdateSeeder.php +++ b/database/seeds/FeatureReflectiveUpdateSeeder.php @@ -21,28 +21,17 @@ public function run() \"check\": { \"all\": [ \"epistemic\", - \"modal\" - ] + \"modal\", + \"affect\" + ], + \"affectVal\": {\"arousal\": 4.95, \"valence\":0, \"dominance\":0} }, \"message\": [ {\"epistemic\" : \"Expressions indicating belief, learning, or knowledge.\"}, - {\"modal\" : \"Expressions indicating self critique<\/span>\"} + {\"modal\" : \"Expressions indicating self critique<\/span>\"}, + {\"affect\" :\"Words associated with strong feelings<\/span>\"} ], - \"css\": [\"epistemic\",\"affect\",\"modall\"] - }, - { - \"name\": \"vocab\", - \"check\": { - \"words\": [ - \"server\", - \"study\", - \"force\" - ] - }, - \"message\": [ - {\"vocab\" :\"One or more keywords missing\"} - ], - \"css\": [\"vocab\"] + \"css\": [\"epistemic\",\"modall\"] }, { \"name\": \"metrics\", @@ -54,6 +43,21 @@ public function run() ], \"css\": [\"metrics\"] }, + { + \"name\": \"filterWords\", + \"check\": { + \"list\": [ + { + \"words\" : + [\"preceptor\",\"supervisor\", \"hospital\", \"Community\", \"Pharmacy\", \"Placement\", \"site\", \"pharmacy\", \"pharmacist\",\"mentor\"], + \"tags\" : + [\"affect\"] + } + ] + }, + \"message\": [], + \"css\": [] + }, { \"name\": \"moves\", \"check\": { diff --git a/database/seeds/FeaturesAnalyticalAccounting.php b/database/seeds/FeaturesAnalyticalAccounting.php new file mode 100644 index 0000000..a8e074c --- /dev/null +++ b/database/seeds/FeaturesAnalyticalAccounting.php @@ -0,0 +1,122 @@ +name = "Analytical Accounting"; + $feature_a->grammar="Analytical"; + $feature_a->rules=json_encode("{ + \"rules\": [ + { + \"name\": \"moves\", + \"check\": { + \"tags\": [ + \"attitude\", + \"emph\", + \"contribution\", + \"novstat\", + \"contrast\", + \"tempstat\", + \"surprise\", + \"nostat\", + \"grow\" + ] + }, + \"message\": [ + {\"contribution\" : \"S<\/span> Summarises or signals the authors goals\"}, + {\"attitude\" : \"P<\/span> Perspective or stance\"}, + {\"emph\" : \"E<\/span> Emphasis to highlight key ideas\"}, + {\"novstat\" : \"N<\/span> Novel improvements in ideas\"}, + {\"contrast\" : \"C Contrasting idea, tension or critical insight\"}, + {\"tempstat\": \"B Background information and previous work\"}, + {\"nostat\": \"Q Question or gap in previous knowledge\"} + ], + \"css\": [\"P\",\"E\", \"S\", \"N\", \"C\", \"B\"], + \"custom\" : \"The analytical report highlights salient rhetorical moves AcaWriter identified in your essay for reflection. For more specific feedback, go to the Feedback tab.<\/span>
Rhetorical Moves<\/h5>\", + \"tab\": 1, + \"tabName\": \"Analytical Feedback\"` + }, + { + \"name\": \"alerts\", + \"method\": \"staticFeed\", + \"check\": { + \"tags\": [ + ], + \"conditions\" : [ + ] + }, + \"message\": [ + {\"txt\" : \"
The rhetorical moves highlighted by AcaWriter are used in good academic writing but use them with caution according to the context. Remember, AcaWriter does not really understand your writing, the way people do. You may have written beautifully crafted nonsense - that's for you to decide! Moreover, writing is complex, and AcaWriter will get it wrong sometimes. If you think it got it wrong, that's fine - now you're thinking about more than spelling, grammar, and plagiarism.<\/small> <\/div>\"} + ], + \"css\": [\"msg1\"], + \"custom\" : \"more feedback\", + \"tab\" :2, + \"tabName\": \"Feedback\", + \"tabEval\": \"static\" + }, + { + \"name\": \"customised\", + \"method\": \"missingSwapTags\", + \"check\": { + \"tags\": [ + \"contribution\", + \"tempstat\", + \"contrast\", + \"attitude\", + \"novstat\" + ], + \"conditions\" : [ + {\"emph\": \"attitude\"}, + {\"nostat\" : \"contrast\"} + ] + }, + \"message\": [ + {\"contribution\": \"
It looks like you are missing a Summary move that highlights the purpose (thesis) statement of your essay and your essay plan. Try including linguistic cues to make this move clearer in your writing. Examples: This essay talks about.., In this essay, I analyse…, This essay consists of three parts… The first part talks about…, In conclusion,... <\/div>\"}, + {\"tempstat\": \"
It looks like you are missing a Background move in your text, which highlights background information and previous literature on the topic. Try including linguistic cues to make this move clearer in your writing. Examples: The past decade has seen ...., Recent studies indicate ... ,It is generally accepted that..., the concept has previously been thought to be... <\/div>\"}, + {\"contrast\": \"
It looks like you are missing Contrast move, which highlights the critical insights in your essay. Try including linguistic cues to make this move clearer in your writing. Examples: However, the issue seems to be..., the study fails to consider, little research has been done..., ...raises various questions... <\/div>\"}, + {\"attitude\": \"
If there is a key idea you did like to position in your essay try including linguistic cues to make this move clearer in your writing. Examples: It is important to note that ...., It makes a proper understanding important...\"} + {\"novstat\": \"
If there is a key idea you did like to novelty in your essay try including this move clearer in your writing. Examples: It is important to note that ...., It makes a proper understanding important...\"} + ], + \"css\": [\"mtags\"], + \"custom\" : \"Feedback\", + \"tab\" :2, + \"tabName\": \"Feedback\", + \"tabEval\": \"dynamic\" + }, + { + \"name\": \"faq\", + \"method\": \"staticFeed\", + \"check\": { + \"tags\": [ + ], + \"conditions\" : [ + ] + }, + \"message\": [ + {\"txt\":\"A list of sample sentences with rhetorical moves, mapped to your essay assessment rubric is provided below:\"}, + {\"txt\" : \"
Sample Sentence<\/th>Essay Assessment Rubric Element<\/th>AcaWriter Move<\/th><\/tr><\/thead>
The concept of good faith has previously been thought<\/strong> to be a work in progress in Australia.<\/td>Engagement with the law and scholarly literature<\/td>Background<\/td><\/tr>
This article will trace<\/strong> the origins of good faith and its development in the common law. This essay contains three parts. The first part will talk about<\/strong> the origins of good faith.<\/td>Statement of thesis, Essay plan<\/td>Summary<\/td><\/tr>
However<\/strong>, where the obligations are found in statute and they conflict with contractual obligations, it is important to note that<\/strong> the former must prevail.<\/td>Identification of relevant issues, Critical analysis and original insight<\/td>Contrast,Emphasis<\/td><\/tr><\/tbody><\/table>\"} + ], + \"css\": [\"msg1\", \"msg2\"], + \"custom\" : \"more feedback\", + \"tab\" :3, + \"tabName\": \"Examples\", + \"tabEval\": \"static\" + } + ] +}"); + $feature_a->save(); + } +} diff --git a/database/seeds/FeaturesAnalyticalAccountingUpdate.php b/database/seeds/FeaturesAnalyticalAccountingUpdate.php new file mode 100644 index 0000000..66d83a3 --- /dev/null +++ b/database/seeds/FeaturesAnalyticalAccountingUpdate.php @@ -0,0 +1,156 @@ +rules= json_encode("{ + \"rules\": [ + { + \"name\": \"amoves\", + \"check\": { + \"tags\": [ + \"attitude\", + \"emph\", + \"contribution\", + \"novstat\", + \"contrast\", + \"tempstat\", + \"nostat\" + ] + }, + \"message\": [ + {\"contribution\" : \"S<\/span> Summarises or signals the authors goals\"}, + {\"attitude\" : \"P<\/span> Perspective or stance\"}, + {\"novstat\" : \"N<\/span> Novel improvements in ideas\"}, + {\"emph\" : \"E<\/span>Emphasis of a significant or an important idea \"}, + {\"contrast\" : \"C Contrasting idea, tension or critical insight\"}, + {\"tempstat\": \"B Background information and previous work\"} + ], + \"css\": [\"P\", \"S\", \"N\", \"C\", \"B\"], + \"custom\" : \"The analytical report highlights salient rhetorical moves AcaWriter identified in your essay for reflection. For more specific feedback, go to the Feedback tab.<\/span>
Rhetorical Moves<\/h5>\", + \"tab\": 1, + \"tabName\": \"Analytical Feedback\" + }, + { + \"name\": \"alerts\", + \"method\": \"staticFeed\", + \"check\": { + \"tags\": [ + ], + \"conditions\" : [ + ] + }, + \"message\": [ + {\"txt\" : \"
The rhetorical moves highlighted by AcaWriter are used in good academic writing but use them with caution according to the context. Remember, AcaWriter does not really understand your writing, the way people do. You may have written beautifully crafted nonsense - that's for you to decide! Moreover, writing is complex, and AcaWriter will get it wrong sometimes. If you think it got it wrong, that's fine - now you're thinking about more than spelling, grammar, and plagiarism.<\/small> <\/div>\"} + ], + \"css\": [\"msg1\"], + \"custom\" : \"more feedback\", + \"tab\" :2, + \"tabName\": \"Feedback\", + \"tabEval\": \"static\" + }, + { + \"name\": \"customised\", + \"method\": \"positiveFeed\", + \"check\": { + \"tags\": [ + \"contribution\", + \"tempstat\", + \"attitude\", + \"contrast\" + ], + \"conditions\" : [ + ] + }, + \"message\":[ + {\"contribution\":\"Summary\"}, + {\"tempstat\":\"Background\"}, + {\"attitude\":\"Perspective\"}, + {\"contrast\":\"Contrast\"} + ], + \"css\": [\"mtags\"], + \"custom\" : \"Feedback\", + \"tab\" :2, + \"tabName\": \"Feedback\", + \"tabEval\": \"dynamic\" + }, + { + \"name\": \"customised\", + \"method\": \"missingSwapTags\", + \"check\": { + \"tags\": [ + \"contribution\", + \"tempstat\", + \"attitude\", + \"contrast\" + ], + \"conditions\" : [ + ] + }, + \"message\": [ + {\"contribution\": \"
It looks like you are missing a Summary move that defines the goal or summary of your report and its sections. Try including linguistic cues to make this move clearer in your writing like: This report defines… , the report first examines.. then.., this section explains... Note that you should use past tense in the executive summary section where you explain your results. <\/div>\"}, + {\"tempstat\": \"
It looks like you are missing a Background move in your text, which highlights previous work on the topic. Some linguistic cues that exemplify background are: Previous market analysis demonstrate that…, …is widely recognised as … , It is generally accepted that...Also, make sure that you provide relevant contextual information on the organisation.<\/div>\"}, + {\"attitude\": \"
It looks like you are missing Perspective and Emphasis moves, which highlight your attitude about an idea in text. Try including linguistic cues to make this move clearer in your writing. Examples: The key factor is that…, They highlight the focus on .., …is a critical aspect of….., Academic theory holds that… <\/div>\"}, + {\"contrast\": \"
It looks like you are missing a Contrast move which highlights disagreement, issues, or alternatives. Try including linguistic cues to make this move clearer in your writing like: Although it is the case… , One challenge is..., However, this problem.. <\/div>\"} + ], + \"css\": [\"mtags\"], + \"custom\" : \"Feedback\", + \"tab\" :2, + \"tabName\": \"Feedback\", + \"tabEval\": \"dynamic\" + }, + { + \"name\": \"faq\", + \"method\": \"staticFeed\", + \"check\": { + \"tags\": [ + ], + \"conditions\" : [ + ] + }, + \"message\": [ + {\"txt\":\"Here are certain rhetorical moves you can look for in your report and example sentences for your reference.

Organisational analysis<\/u>
Where does your report provide contextual information about the organisation’s objectives, strategy, structure and activities?
Defining performance<\/u>
Where does your report provide your perspective P<\/span> about how to define performance or success for the organisation? Where does your report provide emphasis E<\/span> to highlight the most important aspects of performance for the organisation?
Justification of your definition of performance<\/u>
Where does your report provide convincing, persuasive justifications for your definition of performance by proposing novel N<\/span> or critical insights, contrasting ideas or tension C<\/span>? Where does your report justify your definition of performance with reference to prior work or background B<\/span>?
Written communication<\/u>
Where in your report do you use appropriate summary statements S<\/span> to signal the content, sequence and goals of the report?
\"}, + {\"txt\" : \"
Acawriter Move<\/th>Sample Sentences<\/th><\/tr><\/thead>
Summary<\/td>S<\/span> This report defines performance for Nike Inc as a whole from the three main perspectives of economic, social and environmental performance.
S<\/span> This section will explain how sustainability can result in the achievement of organisational objectives and contribute to company success. <\/td><\/tr>
Perspective, Emphasis<\/td>P<\/span> Importantly, research has suggested a link between stronger brand perception and customer loyalty.
E<\/span> Therefore, to effectively measure performance for the Canadian Head Office of Lululemon it is essential to consider how the transformational self-improvement ethos of the company is achieved by analysing non-traditional metrics.<\/td><\/tr>
Background<\/td>B<\/span> Previous market analysis shows that Nike is the world’s largest supplier of athletic shoes, equipment, and apparel.
B<\/span> Such an evaluation by a global organization has been observed previously.<\/td><\/tr>
Contrasting ideas and Issues<\/td>C<\/span> These requirements maintain product quality as unethically produced garments could be of lower quality, damage its reputation and ultimately contradict the companys objective.
C<\/span> While the companys corporate mission is to maintain its market position as a leading brand for an active and mindful lifestyle, a holistic approach to defining performance is necessary given that Lululemons strength lies in its premium image<\/td><\/tr>
Novelty<\/td>N<\/span> This closer connection with their customers allows Nike to create new ideas and convert them into products quicker while also being in touch with their demands.
N<\/span> Nike believes that through investing in employees and communities, they can inspire while also creating a new method of growth (Nike 2018c). <\/td><\/tr><\/tbody><\/table>\"} + ], + \"css\": [\"msg1\", \"msg2\"], + \"custom\" : \"more feedback\", + \"tab\" :3, + \"tabName\": \"Tips\", + \"tabEval\": \"static\" + } + ] +}"); + + $feature->save(); + } +} \ No newline at end of file diff --git a/database/seeds/FeaturesAnalyticalUpdateSeeder.php b/database/seeds/FeaturesAnalyticalUpdateSeeder.php index 3cedc27..15006b2 100644 --- a/database/seeds/FeaturesAnalyticalUpdateSeeder.php +++ b/database/seeds/FeaturesAnalyticalUpdateSeeder.php @@ -106,9 +106,9 @@ public function run() ] }, \"message\": [ - {\"problem21\" : \"
You have indicated the research gap and(or) written about your research problem-Move 2 Establishing a nice (C or Q sentences) before explaining how your research topic is relevant and important which is Move 1 (E or B sentences). It’s better to give some background information on your research topic before jumping straight into your gap and research problem. Acawriter suggests moving Move 1 Establishing the research territory (E or B sentences) before Move 2 Establishing a nice (C or Q sentences). <\/div>\"}, - {\"problem31\" : \"
It seems you have stated how your research fills the gap and/or solves the research problem [Move 3 – Occupying the niche (S or N sentences)] before you have given background information on your research [Move 1 - Establishing the research territory (E or B sentences)]. It is more effective to state how your research fills the gap or solves the research problem at the end of your introduction, as this is an effective transition into the next section of your paper. <\/div>\"}, - {\"problem32\" : \"
It seems you have stated how your research fills the gap and/or solves the research problem [Move 3 – Occupying the niche (S or N sentences)] before you have indicated the gap and/or explained your research problem [Move 2 Establishing a nice (C or Q sentences)]. It is more effective to indicate the gap and explain the research problem before you state your solution and aim of your study. Acawriter suggests putting Move 3 – Occupying the niche (S or N sentences) after Move 2 Establishing a nice (C or Q sentences).<\/div>\"}, + {\"problem21\" : \"
You have indicated the research gap or written about your research problem [Move 2 Establishing a niche (C or Q sentences)] before explaining how your research topic is relevant and important [Move 1 (E or B sentences)]. It’s better to give some background information on your research topic before jumping straight into your gap and research problem. Go back and check if Move 1 Establishing the research territory (E or B sentences) is before Move 2 Establishing a niche (C or Q sentences). <\/div>\"}, + {\"problem31\" : \"
It seems you have stated how your research fills the gap or solves the research problem [Move 3 – Occupying the niche (S or N sentences)] before you have given background information on your research [Move 1 - Establishing the research territory (E or B sentences)]. It is more effective to state how your research fills the gap or solves the research problem at the end of your introduction, as this is an effective transition into the next section of your paper. <\/div>\"}, + {\"problem32\" : \"
It seems you have explained how your research fills the gap or solves the research problem [Move 3 – Occupying the niche (S or N sentences)] before you have indicated the gap or explained your research problem [Move 2 Establishing a niche (C or Q sentences)]. It is more effective to indicate the gap and explain the research problem before you state your solution and aim of your study. Go back and revise your text so that Move 3 – Occupying the niche (S or N sentences) is after Move 2 Establishing a niche (C or Q sentences).<\/div>\"}, {\"missing1\" : \"
It looks like you are missing Move 1 – Establishing a research territory (E or B sentences). Here you should show how your research topic is relevant and important by introducing & reviewing previous research on your topic. For example, recent research indicates that the effects of climate change have…. (for more examples head to the resources tab)<\/div>\"}, {\"missing2\" : \"
It looks like you are missing Move 2 – Establishing a niche (C or Q sentences). Here you should indicate the gap and state the research problem, by explaining how previous research is incomplete or that there are aspects of the research topic that still needs investigating. This can be done by using sentences like these: However, these studies have failed to recognise that…., Limited research exists on……, Despite earlier studies the effects of x remains unclear. (for more examples head to the resources tab) <\/div>\"}, {\"missing3\" : \"
It looks like you are missing Move 3 – Occupying the niche (S or N sentences). Here you should state how your research fills the gap or solves the research problem mentioned in Move 2. You can do this by stating the aim and purpose of your research. For example, this goal of this study, this research shows that.., the purpose of this investigation….(for more examples head to the resources tab)<\/div>\"} @@ -129,7 +129,7 @@ public function run() ] }, \"message\": [ - {\"txt\" : \"
An effective way to introduce your research is by using the Creating a Research Space (C.A.R.S) framework developed by linguist John Swales (1990). Swales (1990) analysed journal articles from a variety of disciplines and found that researchers follow a particular organisational pattern of moves when writing the introduction. The CARS<\/strong> moves are as follows:

<\/i>Establish a research territory<\/strong> to show how the research area is important and worth investigating, by introducing and reviewing previous research
<\/i>Establish a niche<\/strong> by indicating a gap in previous research or raising questions about it
<\/i>Occupy the niche <\/strong> by stating how one’s own research seeks to close\/fill the gap.

Following CARS will help set the scene of your research and will make it easier for others to understand your research.
For more information on how to apply CARS in your research writing please click<\/a> here.<\/div>\"} + {\"txt\" : \"
An effective way to introduce your research is by using the Creating a Research Space (C.A.R.S) framework developed by linguist John Swales (1990). Swales (1990) analysed journal articles from a variety of disciplines and found that researchers follow a particular organisational pattern of moves when writing the introduction. The CARS<\/strong> moves are as follows:

<\/i>Establish a research territory<\/strong> to show how the research area is important and worth investigating, by introducing and reviewing previous research
<\/i>Establish a niche<\/strong> by indicating a gap in previous research or raising questions about it
<\/i>Occupy the niche <\/strong> by stating how one’s own research seeks to close\/fill the gap.

Following CARS will help set the scene of your research and will make it easier for others to understand your research.
For more information on how to apply CARS in your research writing please
click<\/a> here.<\/div>\"} ], \"css\": [\"msg1\", \"msg2\"], \"custom\" : \"more feedback\", diff --git a/package.json b/package.json index 820c06f..b7b4343 100644 --- a/package.json +++ b/package.json @@ -11,25 +11,32 @@ }, "devDependencies": { "axios": "^0.16.2", - "bootstrap": "^4.0.0-beta", - "cross-env": "^5.0.1", - "jquery": "^3.1.1", - "laravel-mix": "^1.6.1", - "lodash": "^4.17.4", - "popper.js": "^1.12.5", - "vue": "^2.5.3" + "bootstrap": "^4.1.1", + "cross-env": "^5.2.0", + "jquery": "^3.3.1", + "laravel-mix": "^1.7.2", + "lodash": "^4.17.10", + "popper.js": "^1.14.3", + "socket.io-client": "^2.1.1", + "vue": "^2.5.16", + "vue-template-compiler": "^2.5.16" }, "dependencies": { "apollo-client": "^1.9.2", - "express": "^4.15.4", + "express": "^4.16.3", "font-awesome": "^4.7.0", - "ioredis": "^3.1.4", - "moment": "^2.18.1", + "ioredis": "^3.2.2", + "laravel-echo": "^1.3.4", + "moment": "^2.20.1", + "node-gyp": "^3.7.0", "node-gyp-install": "^2.2.0", - "socket.io": "^2.0.3", + "node-sass": "^4.9.2", + "nprogress": "^0.2.0", + "socket.io": "^2.1.1", "vue-apollo": "^2.1.0-rc.4", - "vue-froala-wysiwyg": "^2.0.0", - "vue2-editor": "^2.3.0", + "vue-froala-wysiwyg": "^2.8.4", + "vue-js-modal": "^1.3.16", + "vue2-editor": "^2.5.0", "vuex": "^3.0.1" } -} +} \ No newline at end of file diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index de5fdd6..629e48f 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -58,7 +58,6 @@ Vue.component('example-text', require('./components/Example.vue')); Vue.component('ex-doc-editor', require('./components/ExampleAnalyser.vue')); - var socket = io.connect(process.env.MIX_APP_SOCKET); import moment from 'moment'; const app = new Vue({ @@ -78,17 +77,16 @@ const app = new Vue({ }.bind(this)); socket.on('private-dashboard:App\\Events\\InternetConnection\\Heartbeat', function () { - //console.log("ok yes listened"); + // console.log("ok yes listened"); return this.lastHeartBeatReceivedAt = moment().format('LLL'); }.bind(this)); socket.on('private-dashboard:App\\Events\\Tap\\Health', function (data) { - //console.log("ok yes listened tap health"); +// console.log("ok yes listened tap health"); return this.tapHealth=data.health.message; }.bind(this)); - socket.on('private-user-activity:App\\Events\\UserActivity', function (data) { - console.log("into user activity"); + socket.on('private-user-activity:App\\Events\\UserActivity', function (data, dd) { //console.log(data); return this.userActivity.push(data); }.bind(this)); @@ -177,7 +175,6 @@ $(document).ready(function () { $('span[data-toggle=tooltip]').tooltip(); - //assignment feature info show hide let assignment_grammar = $("#grammar").val(); @@ -201,4 +198,4 @@ $(document).ready(function () { -}); \ No newline at end of file +}); diff --git a/resources/assets/js/components/Document.vue b/resources/assets/js/components/Document.vue index ea30fbd..ec5a8c0 100644 --- a/resources/assets/js/components/Document.vue +++ b/resources/assets/js/components/Document.vue @@ -56,7 +56,7 @@ axios.get('/documents/all').then((response) => { this.$data.lists = response.data.documents; }, (err) => { - this.$data.errors.push(e) + this.$data.errors.push(err) }); }, action(what, doc) { @@ -70,7 +70,7 @@ this.fetchDocuments(); }, 3000); }, (err) => { - this.$data.errors.push(e) + this.$data.errors.push(err) }); } } else if(what === 'edit') { diff --git a/resources/assets/js/components/TextAnalyser.vue b/resources/assets/js/components/TextAnalyser.vue index ba389a6..7e782a1 100644 --- a/resources/assets/js/components/TextAnalyser.vue +++ b/resources/assets/js/components/TextAnalyser.vue @@ -6,9 +6,9 @@
--> -
+
-
- - - -
-
+

{{preSetAssignment.name}}

{{draftUpdate.message}} {{auto}} @@ -61,6 +30,7 @@
   
  + Download PDF  @@ -69,7 +39,7 @@
-
+
@@ -259,6 +229,17 @@ } else { return false; } + }, + getLink:function() { + let link='/generate-pdf/'; + let data ={}; + + if(this.preSetAssignment) { + data.id = (this.preSetAssignment.id * 123456); //this is the document id + data.grammar = this.preSetAssignment.feature[0].grammar.toLocaleLowerCase(); + data.name= this.preSetAssignment.name; + } + return link+ JSON.stringify(data); } }, watch :{ @@ -312,7 +293,14 @@ this.btnFeedback = true; if(this.feedbackOpt!=='') { // let data = {'tap': this.tap, 'txt':'', 'action': 'fetch', 'extra': this.attributes}; - let data = {'txt':this.editorContent, 'action': 'fetch', 'extra': this.attributes, 'type':type, 'document':this.preSetAssignment.id}; + let data = { + 'txt':this.editorContent, + 'action': 'fetch', + 'extra': this.attributes, + 'type':type, + 'document':this.preSetAssignment.id, + 'currentFeedback': this.feedback + }; this.$store.dispatch('LOAD_FEEDBACK',data); //this.autoCheck = false; } else { @@ -374,9 +362,10 @@ } }, autoStore(){ - setInterval(this.storeAnalysedDrafts, 60000); + setInterval(this.storeAnalysedDrafts, 300000); }, + } } \ No newline at end of file diff --git a/resources/assets/js/components/analyser/Analytic.vue b/resources/assets/js/components/analyser/Analytic.vue index 4c58cf2..dd08c35 100644 --- a/resources/assets/js/components/analyser/Analytic.vue +++ b/resources/assets/js/components/analyser/Analytic.vue @@ -2,6 +2,14 @@
+ +

-
- - {{processing}} - Loading... - -
+
@@ -47,10 +50,7 @@ - +  
@@ -66,19 +66,7 @@ - - - -
- -
@@ -96,31 +84,25 @@ store, data() { return { - analytic_xlator:[ - {'metrics': 'metrics'}, - {'emph': 'E'}, - {'grow': 'T'}, - {'contrast': 'C'}, - {'contribution': 'S'}, - {'nostat': 'Q'}, - {'tempstat': 'B'}, - {'attitude': 'P'}, - {'novstat': 'N'}, - {'surprise':'S'} - - ], + analytic_xlator: { + metrics: 'metrics', + emph: 'E', + grow: 'T', + contrast: 'C', + contribution: 'S', + nostat: 'Q', + tempstat: 'B', + attitude: 'P', + novstat: 'N', + surprise: 'S' + } } }, mounted:function() { }, methods:{ getAnnotation(ic) { - let tg = ''; - this.analytic_xlator.forEach(function(val){ - if(val[ic]) { - tg = val[ic]; - } - }); + let tg = typeof this.analytic_xlator[ic]!=='undefined' ? this.analytic_xlator[ic] : ''; return tg; }, inLineAnaClasses: function(data) { @@ -171,10 +153,8 @@ let rules = this.feedback.rules; tabs = rules.filter(rule => rule.tab == 1); - console.log(tabs); + tabs.forEach(function(item) { - console.log(item); - console.log(item.check.tags); if(item.check.tags.indexOf(tag)!== -1) mv.push(item.name); }); //console.log(mv); diff --git a/resources/assets/js/components/analyser/Reflective.vue b/resources/assets/js/components/analyser/Reflective.vue index 0b74e2e..b0d8e08 100644 --- a/resources/assets/js/components/analyser/Reflective.vue +++ b/resources/assets/js/components/analyser/Reflective.vue @@ -1,16 +1,26 @@ - +  
@@ -43,6 +47,7 @@
Remember, AcaWriter does not really understand your writing, the way people do. You may have written beautifully crafted nonsense - that's for you to decide! Moreover, writing is complex, and AcaWriter will get it wrong sometimes. If you think it got it wrong, that's fine - now you're thinking about more than spelling, grammar and plagiarism.
+
@@ -58,6 +63,7 @@ store, data() { return { + } }, mounted:function() { @@ -75,11 +81,19 @@ return temp; }, inText: function(data) { + + var self = this; + //console.log(words); if(data.str!=='' && typeof data.expression!== 'undefined') { let str = data.str; - if(data.expression.affect.length > 0) { + if(data.expression.affect.length > 0 && + ( _.includes(data.css, "context") || _.includes(data.css, "challenge") || _.includes(data.css, "change") + ) + ) { data.expression.affect.forEach(function(word) { - str = str.replace(word.text, ""+word.text+""); + if(!self.checkStopWords('affect', word.text)) { + str = str.replace(word.text, "" + word.text + ""); + } }); } @@ -100,6 +114,23 @@ let str = ''; return str; } + }, + checkStopWords:function(tag, word) { + let words = []; + let result = false; + if(this.feedback.rules) { + words = this.feedback.rules.filter((item) => item.name==='filterWords') + .map((item) => item.check.list); + } + + if(words.length > 0) { + words.forEach(function(v) { + if(_.includes(v.tags, tag) && _.includes(v.words, word)) { + return true; + } + }); + } + return result; } }, computed:{ diff --git a/resources/assets/js/store/index.js b/resources/assets/js/store/index.js index c93a07d..e091fac 100644 --- a/resources/assets/js/store/index.js +++ b/resources/assets/js/store/index.js @@ -4,6 +4,15 @@ import axios from 'axios' Vue.use(Vuex) +axios.interceptors.request.use(config => { + NProgress.start(); + return config; +}); + +axios.interceptors.response.use(config => { + NProgress.done(); + return config; +}); const store = new Vuex.Store({ state: { diff --git a/resources/assets/sass/awa.scss b/resources/assets/sass/awa.scss index d79fcf3..538952e 100644 --- a/resources/assets/sass/awa.scss +++ b/resources/assets/sass/awa.scss @@ -22,10 +22,13 @@ .nav-pills .nav-link.active, .nav-pills .show > .nav-link { color: #FFFFFF; - background-color: #000000; + /* background-color: #000000; */ } - +/* assignment */ +.hidefeature { + display: none; +} #sidebar ul li.active > a, a[aria-expanded="true"] { @@ -69,4 +72,25 @@ a[aria-expanded="true"] { .clear { clear: both; height: 60px; - } \ No newline at end of file + } + +#nprogress .bar { + background: #ffc107; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 7px; +} + +#nprogress .peg { + box-shadow: 0 0 10px #ffc107, 0 0 5px #ffc107; +} + +#nprogress .spinner-icon { + border-top-color: #ffc107; + border-left-color: #ffc107; +} \ No newline at end of file diff --git a/resources/views/assignment.blade.php b/resources/views/assignment.blade.php index 0ac93a1..7f012e9 100644 --- a/resources/views/assignment.blade.php +++ b/resources/views/assignment.blade.php @@ -12,29 +12,39 @@
{{ csrf_field() }}
-
+
-
+
+ + +
+
+
+
+
+
+ @foreach($features as $key => $value) + @foreach($value as $feature) +
{!! $feature->info !!}
+ @endforeach + @endforeach +
-
- - -
-

+

diff --git a/resources/views/contact.blade.php b/resources/views/contact.blade.php index e956c2a..ae9c1ea 100644 --- a/resources/views/contact.blade.php +++ b/resources/views/contact.blade.php @@ -49,6 +49,10 @@

+ General Enquiries:
+ cic@uts.edu.au +
+


Academic questions:
Prof. Simon Buckingham Shum (CIC Director)
Simon.BuckinghamShum@uts.edu.au
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 1e3c7ce..44e5724 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -10,6 +10,11 @@ AcaWriter | University of Technology Sydney + + + + + @@ -49,7 +54,7 @@ - + @elseif (Auth::user()->hasRole('staff')) @@ -100,6 +105,7 @@ + @include('layouts.footer') diff --git a/resources/views/pdf/analytical.blade.php b/resources/views/pdf/analytical.blade.php new file mode 100644 index 0000000..fcffe53 --- /dev/null +++ b/resources/views/pdf/analytical.blade.php @@ -0,0 +1,191 @@ + + + + + + + AcaWriter: PDF + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

{{$draft->name}}

+ Genre: {{$draft->grammar}}  + Date:  {!! $draft->created_at !!} +
+
+
+ +
+
+ @foreach($draft->raw->rules as $rule) + @if(!isset($rule->tab)) + @if(isset($rule->custom) ) + {!!$rule->custom!!}
+ @endif + @foreach($rule->message as $msg) + @foreach($msg as $key => $desc) +

{!!$desc!!}

+ @endforeach + @endforeach + @elseif($rule->tab==1) + @if(isset($rule->custom) ) + {!! $rule->custom!!}
+ @endif + @foreach($rule->message as $msg) + @foreach($msg as $key => $desc) +

{!!$desc!!}

+ @endforeach + @endforeach + @endif + @endforeach +
+
+
+ + +
+
+ Feedback with Annotations + +
+
+ +
+
+ {!! $draft->annotated !!} +
+
+ +
+ + +
+
+ @if(isset($draft->raw->tabs)) + @foreach($draft->raw->tabs as $tab) + @foreach($tab as $tabContent) + @foreach($tabContent as $name => $b) + @if($name!== 'faq') + @foreach($b as $msg) + @foreach($msg as $txt) + {!! $txt !!} + @endforeach + @endforeach + @endif + @endforeach + @endforeach + @endforeach + @endif +
+
+ + + + + + + + + diff --git a/resources/views/pdf/reflective.blade.php b/resources/views/pdf/reflective.blade.php new file mode 100644 index 0000000..b8a2803 --- /dev/null +++ b/resources/views/pdf/reflective.blade.php @@ -0,0 +1,172 @@ + + + + + + + AcaWriter: PDF + + + + + + + + + + + + + + + + + + + + + + + + + +
+

{{$draft->name}}

+ Genre: {{$draft->grammar}}  + Date:  {!! $draft->created_at !!} +
+
+
+ +
+
+ @foreach($draft->raw->rules as $rule) + @foreach($rule->message as $msg) + @foreach($msg as $key => $desc) +  {!!$desc!!}
+ @endforeach + @endforeach + @endforeach +
+
+
+ + +
+
+ Feedback with Annotations +
+
+
+ +
+
+ {!! $draft->annotated !!} +
+
+ +
+ + +
+
+ + @foreach($draft->raw->tabs as $tab) + @foreach($tab as $tabContent) + @foreach($tabContent as $b) + @foreach($b as $msg) + @foreach($msg as $txt) + {!! $txt !!} + @endforeach + @endforeach + @endforeach + @endforeach + @endforeach + +
+
+ + + + + + + + + diff --git a/resources/views/pdf/view.blade.php b/resources/views/pdf/view.blade.php deleted file mode 100644 index a821d7a..0000000 --- a/resources/views/pdf/view.blade.php +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - AcaWriter: PDF - - - - - - - - - -
-
-

Feedback for document

-
-
- - - - - - - diff --git a/resources/views/terms.blade.php b/resources/views/terms.blade.php index 47f5dc6..5131b2a 100644 --- a/resources/views/terms.blade.php +++ b/resources/views/terms.blade.php @@ -12,9 +12,11 @@

The Connected Intelligence Centre (CIC) complies with the UTS Governance strategy toward Privacy, as well as associated regulations and practices. See Privacy at UTS for more information. In addition to the regular data collection associated with the normal running of a UTS teaching and research unit, CIC engages in activities across the University that will from time to time mean: - The collection of additional data (eg student employment industry categories) - Accessing existing data and reusing for a purpose not originally intended with its collection (eg, Learning Management System (LMS) logins) - Combining more than one form of a data with another (eg LMS logins and grades) +

    +
  • The collection of additional data (eg student employment industry categories)
  • +
  • Accessing existing data and reusing for a purpose not originally intended with its collection (eg, Learning Management System (LMS) logins)
  • +
  • Combining more than one form of a data with another (eg LMS logins and grades)
  • +

Collection

diff --git a/routes/web.php b/routes/web.php index 42c39bf..5be8e65 100644 --- a/routes/web.php +++ b/routes/web.php @@ -110,4 +110,4 @@ //Genaerate and download pdf -/* Route::get('/generate-pdf/{draftId}', 'PdfGeneratorController@pdfview'); */ \ No newline at end of file + Route::get('/generate-pdf/{draftId}', 'PdfGeneratorController@pdfview'); \ No newline at end of file