From 751b50448218c032d276b201a70f706ca945ba21 Mon Sep 17 00:00:00 2001 From: Morgan Lesko <15270653+rockhopsoft@users.noreply.github.com> Date: Wed, 3 Jun 2020 02:52:04 -0400 Subject: [PATCH] Complaint Management Tool Upgrades And evolving the Department Management. --- README.md | 6 +- src/Controllers/DepartmentScores.php | 67 ++-- src/Controllers/OpenComplaintConditions.php | 21 +- src/Controllers/OpenComplaintEmails.php | 14 +- src/Controllers/OpenComplaintPrints.php | 2 +- src/Controllers/OpenComplaintSaves.php | 2 +- src/Controllers/OpenDashAdmin.php | 16 +- src/Controllers/OpenDepts.php | 184 +++++++++-- src/Controllers/OpenPolice.php | 1 + src/Controllers/OpenPoliceAdmin.php | 4 +- src/Controllers/OpenPoliceAdminMenu.php | 5 - src/Controllers/OpenPolicePCIF.php | 287 ++++++++++++++++++ src/Controllers/OpenPoliceUtils.php | 41 ++- src/Controllers/OpenReport.php | 77 ++++- src/Controllers/OpenReportTools.php | 46 +-- src/Controllers/OpenReportToolsAdmin.php | 3 +- src/Controllers/OpenSessDataOverride.php | 10 +- src/Controllers/OpenVolunteers.php | 206 ++++++++++--- src/Models/OPZeditDepartments.php | 3 +- src/Models/OPZeditOversight.php | 2 +- src/Models/OPzComplaintReviews.php | 2 +- src/Models/OPzVolunStatDays.php | 2 +- src/Models/OPzVolunUserInfo.php | 2 +- .../screenshot-protip-bottom-nav-jump.jpg | Bin 6586 -> 0 bytes .../screenshot-protip-bottom-nav-progress.jpg | Bin 2982 -> 0 bytes src/Views/ajax/search-police-dept.blade.php | 5 +- src/Views/api/pcif-schema-header.blade.php | 14 + ...t-page-filing-instructs-file-btn.blade.php | 14 +- .../dept-page-filing-instructs.blade.php | 12 +- .../nodes/1211-volun-home-all-depts.blade.php | 24 +- ...dmin-complaints-listing-previews.blade.php | 2 +- .../nodes/1712-report-inc-history.blade.php | 2 +- ...ort-inc-staff-tools-first-review.blade.php | 10 +- ...12-report-inc-staff-tools-status.blade.php | 72 +++-- .../1712-report-inc-staff-tools.blade.php | 63 ++-- ...-report-inc-tools-progress-dates.blade.php | 3 +- .../1714-report-inc-owner-tools.blade.php | 11 +- src/Views/nodes/2234-beta-listing.blade.php | 2 +- .../2713-dept-page-calls-action.blade.php | 9 +- .../2715-dept-page-recent-reports.blade.php | 9 +- .../2718-dept-page-how-to-file.blade.php | 8 +- ...ts-accessibility-overview-public.blade.php | 278 +++++++++++++---- src/Views/volun/admPrintDeptEdit.blade.php | 2 +- src/Views/volun/dept-rows.blade.php | 13 +- .../volun/volunteer-recent-edits.blade.php | 24 +- src/routes.php | 35 +++ 46 files changed, 1268 insertions(+), 347 deletions(-) create mode 100644 src/Controllers/OpenPolicePCIF.php delete mode 100644 src/Uploads/screenshot-protip-bottom-nav-jump.jpg delete mode 100644 src/Uploads/screenshot-protip-bottom-nav-progress.jpg create mode 100644 src/Views/api/pcif-schema-header.blade.php diff --git a/README.md b/README.md index 97a5f5a..365099a 100755 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ XML included an automatically generated schema, eg.
* php: >=7.2.5 * laravel/laravel: 7.6.* -* rockhopsoft/survloop: >=0.2.15 +* rockhopsoft/survloop: >=0.2.16 * flexyourrights/openpolice-departments: 0.1.* * flexyourrights/openpolice-website: 0.1.* @@ -81,7 +81,7 @@ DB_USERNAME=homestead DB_PASSWORD=secret ``` -You could do things like install Laravel's out-of-the-box user authentication tools, and push the vendor file copies where they need to be: +Next, install Laravel's out-of-the-box user authentication tools, and push the vendor file copies where they need to be: ``` $ composer require laravel/ui $ php artisan ui vue --auth @@ -98,7 +98,7 @@ $ nano composer.json ... "require": { ... - "rockhopsoft/survloop": "^0.2.16", + "rockhopsoft/survloop": "^0.2.4", "flexyourrights/openpolice": "^0.2.16", ... }, diff --git a/src/Controllers/DepartmentScores.php b/src/Controllers/DepartmentScores.php index ce5c757..543bbbb 100644 --- a/src/Controllers/DepartmentScores.php +++ b/src/Controllers/DepartmentScores.php @@ -16,8 +16,8 @@ use App\Models\OPDepartments; use App\Models\OPOversight; use App\Models\OPzComplaintReviews; -use App\Models\OPZeditDepartments; -use App\Models\OPZeditOversight; +use App\Models\OPzEditDepartments; +use App\Models\OPzEditOversight; use App\Models\OPOversightModels; class DepartmentScores @@ -236,20 +236,14 @@ public function loadAllDepts($searchFilts = []) $deptName = str_replace('Police Dept', '', trim($dept->dept_name)); $deptName = str_replace('Police Department', '', $deptName); $deptName = trim(str_replace('Department', 'Dept', $deptName)); - $this->deptNames[$dept->dept_id] = $deptName . ', ' . $dept->dept_address_state; - $this->deptOvers[$dept->dept_id] = OPOversight::where('over_dept_id', $dept->dept_id) - ->whereNotNull('over_agnc_name') - ->where('over_agnc_name', 'NOT LIKE', '') - ->orderBy('over_type', 'asc') + $this->deptNames[$dept->dept_id] = $deptName + . ', ' . $dept->dept_address_state; + $this->deptOvers[$dept->dept_id]["ia"] = OPOversight::where('over_dept_id', $dept->dept_id) + ->where('over_type', $GLOBALS["SL"]->x["defOverIA"]) + ->first(); + $this->deptOvers[$dept->dept_id]["civ"] = OPOversight::where('over_dept_id', $dept->dept_id) + ->where('over_type', $GLOBALS["SL"]->x["defOverCiv"]) ->first(); - if (isset($this->deptOvers[$dept->dept_id]->over_type) - && $this->deptOvers[$dept->dept_id]->over_type == $GLOBALS["SL"]->x["defOverCiv"]) { - $this->deptScore[$dept->dept_id] = OPOversight::where('over_dept_id', $dept->dept_id) - ->whereNotNull('over_agnc_name') - ->where('over_agnc_name', 'NOT LIKE', '') - ->where('over_type', $GLOBALS["SL"]->x["defOverIA"]) - ->first(); - } } } } @@ -261,7 +255,7 @@ public function loadAllDepts($searchFilts = []) protected function recheckVerified() { $verifList = $verifDates = $verifCnt = []; - $chk = OPZeditOversight::where(function ($query) { + $chk = OPzEditOversight::where(function ($query) { $query->where('zed_over_online_research', 1) ->orWhere('zed_over_made_dept_call', 1) ->orWhere('zed_over_made_ia_call', 1); @@ -302,7 +296,8 @@ protected function recheckVerified() if (isset($verifDates[$deptID])) { $dept = OPDepartments::find($deptID); if ($dept && isset($dept->dept_id)) { - $dept->dept_verified = date("Y-m-d H:i:s", strtotime($verifDates[$deptID])); + $time = strtotime($verifDates[$deptID]); + $dept->dept_verified = date("Y-m-d H:i:s", $time); $dept->save(); } } @@ -320,7 +315,8 @@ public function recalcAllDepts() $this->loadAllDepts(); if ($this->scoreDepts->isNotEmpty()) { foreach ($this->scoreDepts as $i => $dept) { - if ($this->deptOvers[$dept->dept_id]) { + $id = $dept->dept_id; + if ($this->deptOvers[$id]["ia"]) { $this->scoreDepts[$i]->dept_score_openness = 0; foreach ($this->vals as $type => $specs) { $score = $this->checkRecFld($specs, $dept->dept_id); @@ -329,12 +325,20 @@ public function recalcAllDepts() $this->stats[$type]++; } } - if (isset($this->deptOvers[$dept->dept_id]->over_email) - && trim($this->deptOvers[$dept->dept_id]->over_email) != '' - && isset($this->deptOvers[$dept->dept_id]->over_way_sub_email) - && intVal($this->deptOvers[$dept->dept_id]->over_way_sub_email) == 1 - && isset($this->deptOvers[$dept->dept_id]->over_official_form_not_req) - && intVal($this->deptOvers[$dept->dept_id]->over_official_form_not_req) == 1) { + $hasEmail = false; + if ((isset($dept->dept_email) && trim($dept->dept_email) != '') + || (isset($this->deptOvers[$id]["ia"]->over_email) + && trim($this->deptOvers[$id]["ia"]->over_email) != '') + || ($this->deptOvers[$id]["civ"] + && isset($this->deptOvers[$id]["civ"]->over_email) + && trim($this->deptOvers[$id]["civ"]->over_email) != '')) { + $hasEmail = true; + } + if ($hasEmail + && isset($this->deptOvers[$id]["ia"]->over_way_sub_email) + && intVal($this->deptOvers[$id]["ia"]->over_way_sub_email) == 1 + && isset($this->deptOvers[$id]["ia"]->over_official_form_not_req) + && intVal($this->deptOvers[$id]["ia"]->over_official_form_not_req) == 1) { $this->scoreDepts[$i]->dept_op_compliant = 1; } else { $this->scoreDepts[$i]->dept_op_compliant = 0; @@ -357,7 +361,7 @@ public function checkRecFld($specs, $deptID, $overrow = null) if ($deptID <= 0) { return 0; } - $overrow = $this->deptOvers[$deptID]; + $overrow = $this->deptOvers[$deptID]["ia"]; if (isset($this->deptScore[$deptID])) { $overrow = $this->deptScore[$deptID]; } @@ -446,8 +450,10 @@ public function loadDeptStuff($deptID = -3) } $d["iaRow"]->save(); } - if (isset($d["deptRow"]->dept_name) && trim($d["deptRow"]->dept_name) != '') { - if (!isset($d["iaRow"]->over_agnc_name) || trim($d["iaRow"]->over_agnc_name) == '') { + if (isset($d["deptRow"]->dept_name) + && trim($d["deptRow"]->dept_name) != '') { + if (!isset($d["iaRow"]->over_agnc_name) + || trim($d["iaRow"]->over_agnc_name) == '') { $d["iaRow"]->over_agnc_name = $d["deptRow"]->dept_name; $d["iaRow"]->save(); } @@ -458,7 +464,8 @@ public function loadDeptStuff($deptID = -3) $d["deptAddy"] .= $d["deptRow"]->dept_address2 . ', '; } $d["deptAddy"] .= $d["deptRow"]->dept_address_city . ', ' - . $d["deptRow"]->dept_address_state . ' ' . $d["deptRow"]->dept_address_zip; + . $d["deptRow"]->dept_address_state . ' ' + . $d["deptRow"]->dept_address_zip; $d["iaAddy"] = ''; if (isset($d["iaRow"]->over_address) && trim($d["iaRow"]->over_address) != '') { @@ -508,6 +515,10 @@ public function loadDeptStuff($deptID = -3) ]; } } + $chk = OPzEditDepartments::where('zed_dept_dept_id', $deptID) + ->select('zed_dept_dept_id') + ->get(); + $d["editCnt"] = $chk->count(); $GLOBALS["SL"]->x["depts"][$deptID] = $d; } return true; diff --git a/src/Controllers/OpenComplaintConditions.php b/src/Controllers/OpenComplaintConditions.php index e9c15c1..c8801ff 100644 --- a/src/Controllers/OpenComplaintConditions.php +++ b/src/Controllers/OpenComplaintConditions.php @@ -556,6 +556,22 @@ protected function condPrintAnonOnly($complaint) return 0; } + /** + * Checks whether or not the incident record indicates + * that the location should be printed. + * + * @return int + */ + protected function canPrintIncidentLocation() + { + return (isset($this->sessData->dataSets["incidents"]) + && isset($this->sessData->dataSets["incidents"][0]) + && isset($this->sessData->dataSets["incidents"][0]->inc_public) + && intVal($this->sessData->dataSets["incidents"][0]->inc_public) == 1 + && in_array($this->sessData->dataSets["complaints"][0]->com_status, + [200, 201, 202, 203, 204])); + } + /** * Checks whether or not the incident location * should be printed for the current page load. @@ -564,10 +580,7 @@ protected function condPrintAnonOnly($complaint) */ protected function condPrintIncidentLocation() { - if (isset($this->sessData->dataSets["incidents"]) - && isset($this->sessData->dataSets["incidents"][0]) - && isset($this->sessData->dataSets["incidents"][0]->inc_public) - && intVal($this->sessData->dataSets["incidents"][0]->inc_public) == 1) { + if ($this->canPrintIncidentLocation()) { return 1; } if ((isset($this->v["isAdmin"]) && $this->v["isAdmin"]) diff --git a/src/Controllers/OpenComplaintEmails.php b/src/Controllers/OpenComplaintEmails.php index 7dee75c..8df2d6f 100644 --- a/src/Controllers/OpenComplaintEmails.php +++ b/src/Controllers/OpenComplaintEmails.php @@ -23,7 +23,8 @@ class OpenComplaintEmails extends OpenPoliceEvents protected function postContactEmail($nID) { $this->postNodeLoadEmail($nID); - if ($GLOBALS["SL"]->REQ->has('n831fld') && trim($GLOBALS["SL"]->REQ->n831fld) != '') { + if ($GLOBALS["SL"]->REQ->has('n831fld') + && trim($GLOBALS["SL"]->REQ->n831fld) != '') { return true; } $emaSubject = $this->postDumpFormEmailSubject(); @@ -85,7 +86,8 @@ protected function postDumpFormEmailSubject() } return $ret; } - return $GLOBALS["SL"]->sysOpts["site-name"] . ': ' . $GLOBALS["SL"]->treeRow->tree_name; + return $GLOBALS["SL"]->sysOpts["site-name"] . ': ' + . $GLOBALS["SL"]->treeRow->tree_name; } protected function processTokenAccessRedirExtra() @@ -633,17 +635,15 @@ public function prepEmailComDataRow($deptRow, $cnt) ->where('lnk_com_over_dept_id', $deptRow->dept_id) //->where('lnk_com_over_over_id', $this->v["comDepts"][0][$w]->over_id) ->first(); - /* - if (!$this->v["comDepts"][$cnt]["overDates"] + /* if (!$this->v["comDepts"][$cnt]["overDates"] || !isset($this->v["comDepts"][$cnt]["overDates"]->lnk_com_dept_id)) { $lnk = new OPLinksComplaintOversight; $lnk->lnk_com_over_complaint_id = $this->coreID; $lnk->lnk_com_over_dept_id = $deptRow->dept_id; $lnk->lnk_com_over_over_id = $this->v["comDepts"][0][$w]->over_id; + $lnk->save(); $this->v["comDepts"][$cnt]["overDates"] = $lnk; - $this->v["comDepts"][$cnt]["overDates"]->save(); - } - */ + } */ return true; } diff --git a/src/Controllers/OpenComplaintPrints.php b/src/Controllers/OpenComplaintPrints.php index 4e72e94..3bf874b 100644 --- a/src/Controllers/OpenComplaintPrints.php +++ b/src/Controllers/OpenComplaintPrints.php @@ -113,7 +113,7 @@ protected function printEndOfComplaintRedirect($nID) . $this->sessData->dataSets["compliments"][0]->compli_public_id; } $spin = $GLOBALS["SL"]->sysOpts["spinner-code"]; - $this->restartSess($GLOBALS["SL"]->REQ); + //$this->restartSess($GLOBALS["SL"]->REQ); return '

All Done!
' . 'Taking you to your finished ' . (($nID == 270) ? 'complaint' : 'compliment') diff --git a/src/Controllers/OpenComplaintSaves.php b/src/Controllers/OpenComplaintSaves.php index 3cc4bae..14cd221 100644 --- a/src/Controllers/OpenComplaintSaves.php +++ b/src/Controllers/OpenComplaintSaves.php @@ -106,7 +106,7 @@ protected function saveStartTime($curr) $date = '0000-00-00'; } $time = $this->postFormTimeStr($curr->nID); - if ($time === null) { + if ($time === null || strlen($time) != 8) { $date .= ' 00:00:00'; } else { $date .= ' ' . $time; diff --git a/src/Controllers/OpenDashAdmin.php b/src/Controllers/OpenDashAdmin.php index 4fcee3d..fe963e3 100644 --- a/src/Controllers/OpenDashAdmin.php +++ b/src/Controllers/OpenDashAdmin.php @@ -16,8 +16,8 @@ use App\Models\OPzComplaintReviews; use App\Models\OPLinksComplaintOversight; use App\Models\OPDepartments; -use App\Models\OPZeditDepartments; -use App\Models\OPZeditOversight; +use App\Models\OPzEditDepartments; +use App\Models\OPzEditOversight; use App\Models\OPzVolunStatDays; use App\Models\OPTesterBeta; use SurvLoop\Controllers\Stats\SurvTrends; @@ -340,10 +340,10 @@ public function volunDeptsRecent() ]; foreach ($statRanges as $i => $stat) { $this->v["statTots"][$i] = [ $stat[0] ]; - $this->v["statTots"][$i][] = OPZeditDepartments::distinct('zed_dept_user_id') + $this->v["statTots"][$i][] = OPzEditDepartments::distinct('zed_dept_user_id') ->where('zed_dept_dept_verified', '>', $stat[1]) ->count(); - $this->v["statTots"][$i][] = OPZeditDepartments::select('zed_dept_id') + $this->v["statTots"][$i][] = OPzEditDepartments::select('zed_dept_id') ->where('zed_dept_dept_verified', '>', $stat[1]) ->count(); $overType = " `zed_over_over_type` LIKE '303'"; @@ -376,15 +376,15 @@ public function volunDepts() { $this->volunDeptsRecent(); $deptEdits = []; - $recentEdits = OPZeditDepartments::take(100) + $recentEdits = OPzEditDepartments::take(100) ->orderBy('zed_dept_dept_verified', 'desc') ->get(); if ($recentEdits->isNotEmpty()) { foreach ($recentEdits as $i => $edit) { - $iaEdit = OPZeditOversight::where('zed_over_zed_dept_id', $edit->zed_dept_id) + $iaEdit = OPzEditOversight::where('zed_over_zed_dept_id', $edit->zed_dept_id) ->where('zed_over_over_type', 303) ->first(); - $civEdit = OPZeditOversight::where('zed_over_zed_dept_id', $edit->zed_dept_id) + $civEdit = OPzEditOversight::where('zed_over_zed_dept_id', $edit->zed_dept_id) ->where('zed_over_over_type', 302) ->first(); $userObj = User::find($edit->zed_dept_user_id); @@ -498,7 +498,7 @@ public function recalcVolunStats() } } - $edits = OPZeditOversight::where('op_z_edit_oversight.zed_over_over_type', 303) + $edits = OPzEditOversight::where('op_z_edit_oversight.zed_over_over_type', 303) ->join('op_z_edit_departments', 'op_z_edit_departments.zed_dept_id', '=', 'op_z_edit_oversight.zed_over_zed_dept_id') ->where('op_z_edit_oversight.zed_over_over_verified', '>', date("Y-m-d", strtotime($startDate)).' 00:00:00') diff --git a/src/Controllers/OpenDepts.php b/src/Controllers/OpenDepts.php index 19caf30..5616051 100644 --- a/src/Controllers/OpenDepts.php +++ b/src/Controllers/OpenDepts.php @@ -15,16 +15,18 @@ use Illuminate\Support\Str; use Illuminate\Http\Request; use App\Models\OPDepartments; -use App\Models\OPZeditDepartments; -use App\Models\OPZeditOversight; +use App\Models\OPzEditDepartments; +use App\Models\OPzEditOversight; use App\Models\OPzVolunTmp; use App\Models\OPOversight; use App\Models\OPLinksComplaintOversight; use App\Models\OPLinksComplimentOversight; +use SurvLoop\Controllers\PageLoadUtils; +use OpenPolice\Controllers\OpenPolice; use OpenPolice\Controllers\DepartmentScores; -use OpenPolice\Controllers\OpenListing; +use OpenPolice\Controllers\OpenPolicePCIF; -class OpenDepts extends OpenListing +class OpenDepts extends OpenPolicePCIF { /** * Print ajax load of search results to select a police department. @@ -250,19 +252,23 @@ protected function printDeptEditHeader() "callIA" => 0 ]; - if (!isset($this->v["deptRow"]->dept_id) || intVal($this->v["deptRow"]->dept_id) <= 0) { + if (!isset($this->v["deptRow"]->dept_id) + || intVal($this->v["deptRow"]->dept_id) <= 0) { return $this->redir('/dashboard/volunteer'); } - $this->v["editsDept"] = OPZeditDepartments::where('zed_dept_dept_id', $this->v["deptRow"]->dept_id) + $this->v["editsDept"] = OPzEditDepartments::where( + 'zed_dept_dept_id', $this->v["deptRow"]->dept_id) ->orderBy('zed_dept_dept_verified', 'desc') ->get(); if ($this->v["editsDept"]->isNotEmpty()) { foreach ($this->v["editsDept"] as $i => $edit) { - $this->v["editsIA"][$i] = OPZeditOversight::where('zed_over_zed_dept_id', $edit->zed_dept_id) + $this->v["editsIA"][$i] = OPzEditOversight::where( + 'zed_over_zed_dept_id', $edit->zed_dept_id) ->where('zed_over_over_type', $this->overWhichDefID('IA')) ->first(); - $this->v["editsCiv"][$i] = OPZeditOversight::where('zed_over_zed_dept_id', $edit->zed_dept_id) + $this->v["editsCiv"][$i] = OPzEditOversight::where( + 'zed_over_zed_dept_id', $edit->zed_dept_id) ->where('zed_over_over_type', $this->overWhichDefID('civ')) ->first(); if ($this->v["editsIA"][$i]) { @@ -280,9 +286,11 @@ protected function printDeptEditHeader() } } if (!isset($this->v["userNames"][$edit->zed_dept_user_id])) { - $this->v["userNames"][$edit->zed_dept_user_id] = $this->printUserLnk($edit->zed_dept_user_id); + $this->v["userNames"][$edit->zed_dept_user_id] + = $this->printUserLnk($edit->zed_dept_user_id); } if ($this->v["user"]->hasRole('administrator|staff')) { + $type = $GLOBALS["SL"]->def->getVal('Department Types', $edit->dept_type); $this->v["recentEdits"] .= view( 'vendor.openpolice.volun.admPrintDeptEdit', [ @@ -291,7 +299,7 @@ protected function printDeptEditHeader() "deptEdit" => $edit, "iaEdit" => $this->v["editsIA"][$i], "civEdit" => $this->v["editsCiv"][$i], - "deptType" => $GLOBALS["SL"]->def->getVal('Department Types', $edit->dept_type) + "deptType" => $type ] )->render(); } @@ -594,7 +602,6 @@ protected function saveEditLog($nID) ); $over = $this->getOverRow('civ'); if ($over && isset($over->over_id)) { - $this->sessData->createTblExtendFlds( 'oversight', $over->getKey(), @@ -717,6 +724,8 @@ protected function publicDeptAccessMap($nID = -3) $addy = $GLOBALS["SL"]->printRowAddy($dept, 'Dept'); if (trim($addy) != '') { list($lat, $lng) = $GLOBALS["SL"]->states->getLatLng($addy); + $GLOBALS["SL"]->pageJAVA .= ' console.log("' + . $addy . ', ' . $lat . ', ' . $lng . '"); '; $this->v["deptScores"]->scoreDepts[$i]->dept_address_lat = $lat; $this->v["deptScores"]->scoreDepts[$i]->dept_address_lng = $lng; $this->v["deptScores"]->scoreDepts[$i]->save(); @@ -807,16 +816,89 @@ protected function printDeptOverPublic($nID) */ protected function printDeptOverPublicTop50s($nID) { - + $biggest = []; + if ($this->v["deptScores"]->scoreDepts->isNotEmpty()) { + foreach ($this->v["deptScores"]->scoreDepts as $d => $dept) { + $biggest[] = [ + "id" => $dept->dept_id, + "ind" => $d, + "name" => $dept->dept_name . ', ' . $dept->dept_address_state, + "employees" => $dept->dept_tot_officers + ]; + } + } + $nameSort = $biggest; + usort($biggest, function($a, $b) { + return $b["employees"] - $a["employees"]; + }); + usort($nameSort, function($a, $b) { + return $a["name"] <=> $b["name"]; + }); + $this->loadStateListings(); return view( 'vendor.openpolice.nodes.2804-depts-accessibility-overview-public', [ "nID" => $nID, - "deptScores" => $this->v["deptScores"] + "biggest" => $biggest, + "nameSort" => $nameSort, + "deptScores" => $this->v["deptScores"], + "stateLists" => $this->v["stateLists"], + "stateAvg" => $this->v["stateAvg"], + "deptCnt" => $this->v["deptCnt"] ] )->render(); } + /** + * Prints the main public listing of + * all departments within one state. + * + * @return string + */ + protected function loadStateListings() + { + $this->v["stateLists"] = null; + $this->v["stateAvg"] = 0; + $this->v["deptCnt"] = OPDepartments::where('dept_name', 'NOT LIKE', '') + ->select('dept_id') + ->count(); + if ($GLOBALS["SL"]->REQ->has('state')) { + $state = trim($GLOBALS["SL"]->REQ->get('state')); + if ($state != '') { + $fedDef = $GLOBALS["SL"]->def->getID( + 'Department Types', + 'Federal Law Enforcement' + ); + if (trim($GLOBALS["SL"]->REQ->get('state')) == 'US') { + $this->v["stateLists"] = OPDepartments::where('dept_type', $fedDef) + ->orderBy('dept_name', 'asc') + ->get(); + } else { + $this->v["stateLists"] = OPDepartments::where( + 'dept_type', 'NOT LIKE', $fedDef) + ->where('dept_address_state', $state) + ->orderBy('dept_name', 'asc') + ->get(); + } + if ($this->v["stateLists"]->isNotEmpty()) { + $cnt = 0; + foreach ($this->v["stateLists"] as $dept) { + if (isset($dept->dept_score_openness) + && isset($dept->dept_verified) + && trim($dept->dept_verified) != '') { + $this->v["stateAvg"] += intVal($dept->dept_score_openness); + $cnt++; + } + } + if ($cnt > 0) { + $this->v["stateAvg"] = $this->v["stateAvg"]/$cnt; + } + } + } + } + return true; + } + /** * Prints the titles for main public listing of all departments * with accessibility scores. @@ -1079,6 +1161,38 @@ public function deptPage(Request $request, $deptSlug = '') return $this->index($request); } + /** + * Log the session variable for this department submissions. + * + * @param string $deptSlug + * @return boolean + */ + public function logDeptSessTag($deptSlug = '') + { + $deptRow = OPDepartments::where('dept_slug', $deptSlug) + ->first(); + if ($deptRow && isset($deptRow->dept_id)) { + session()->put('opcDeptID', $deptRow->dept_id); + } + return true; + } + + /** + * Loads the department's profile affiliate landing page to start + * the complaint process — from their slug in the page URL. + * + * @param Illuminate\Http\Request $request + * @param string $deptSlug + * @return string + */ + public function shareComplaintDept(Request $request, $deptSlug = '') + { + $url = '/filing-your-police-complaint/' . $deptSlug; + $this->loadPageVariation($request, 1, 7, $url); + $this->logDeptSessTag($deptSlug); + return $this->index($request); + } + /** * Loads the department's profile affiliate landing page to start * the survey process — from their slug in the page URL. @@ -1091,11 +1205,7 @@ public function shareStoryDept(Request $request, $deptSlug = '') { $url = '/complaint-or-compliment/' . $deptSlug; $this->loadPageVariation($request, 1, 24, $url); - $deptRow = OPDepartments::where('dept_slug', $deptSlug) - ->first(); - if ($deptRow && isset($deptRow->dept_id)) { - session()->put('opcDeptID', $deptRow->dept_id); - } + $this->logDeptSessTag($deptSlug); return $this->index($request); } @@ -1114,29 +1224,43 @@ public function getOverUpdateRow($cid, $deptID) 'Civilian Oversight' ); if (!isset($this->v["currOverRow"])) { - $this->v["currOverRow"] = NULL; + $this->v["currOverRow"] = []; + } + if (!isset($this->v["currOverRow"][$deptID])) { + $this->v["currOverRow"][$deptID] = NULL; $overs = OPOversight::where('over_dept_id', $deptID) ->orderBy('created_at', 'asc') ->get(); if ($overs->isNotEmpty()) { if ($overs->count() == 1) { - $this->v["currOverRow"] = $overs[0]; + $this->v["currOverRow"][$deptID] = $overs[0]; } else { foreach ($overs as $i => $ovr) { if ($ovr && isset($ovr->over_type) && $ovr->over_type == $civDef) { - $this->v["currOverRow"] = $ovr; + $this->v["currOverRow"][$deptID] = $ovr; } } } } } if (!isset($this->v["currOverUpdateRow"])) { - $this->v["currOverUpdateRow"] = OPLinksComplaintOversight::where( + $this->v["currOverUpdateRow"] = []; + } + if (!isset($this->v["currOverUpdateRow"][$deptID])) { + $this->v["currOverUpdateRow"][$deptID] = OPLinksComplaintOversight::where( 'lnk_com_over_complaint_id', $this->coreID) ->where('lnk_com_over_dept_id', $deptID) ->first(); + if (!$this->v["currOverUpdateRow"][$deptID] + || !isset($this->v["currOverUpdateRow"][$deptID]->lnk_com_over_id)) { + $lnk = new OPLinksComplaintOversight; + $lnk->lnk_com_over_complaint_id = $this->coreID; + $lnk->lnk_com_over_dept_id = $deptID; + $lnk->save(); + $this->v["currOverUpdateRow"][$deptID] = $lnk; + } } return $this->v["currOverUpdateRow"]; } @@ -1225,5 +1349,21 @@ protected function getOverRow($which = 'IA') } return []; } + + /** + * Executes standard XML generations for department export. + * + * @return string + */ + public function apiDeptAllXml(Request $request) + { + $load = new PageLoadUtils; + $load->syncDataTrees($request, 1, 36); + $custLoop = new OpenPolice($request, -3, 1, 36, true); + return $custLoop->xmlAll($request); + } + + + } \ No newline at end of file diff --git a/src/Controllers/OpenPolice.php b/src/Controllers/OpenPolice.php index 03f53d4..7044386 100755 --- a/src/Controllers/OpenPolice.php +++ b/src/Controllers/OpenPolice.php @@ -139,6 +139,7 @@ protected function customNodePrint(&$curr = null) } return ''; } elseif ($nID == 1714) { + $this->processOwnerUpdate(); $this->saveComplaintAdmin(); return $this->printComplaintOwner(); } elseif ($nID == 1780) { diff --git a/src/Controllers/OpenPoliceAdmin.php b/src/Controllers/OpenPoliceAdmin.php index 6581a20..b38958d 100755 --- a/src/Controllers/OpenPoliceAdmin.php +++ b/src/Controllers/OpenPoliceAdmin.php @@ -24,8 +24,8 @@ use App\Models\OPOversight; use App\Models\OPLinksComplaintDept; use App\Models\OPCustomers; -use App\Models\OPZeditDepartments; -use App\Models\OPZeditOversight; +use App\Models\OPzEditDepartments; +use App\Models\OPzEditOversight; use App\Models\OPzVolunStatDays; use App\Models\OPzVolunUserInfo; use App\Models\SLEmails; diff --git a/src/Controllers/OpenPoliceAdminMenu.php b/src/Controllers/OpenPoliceAdminMenu.php index 79d5bb6..acc6ee9 100644 --- a/src/Controllers/OpenPoliceAdminMenu.php +++ b/src/Controllers/OpenPoliceAdminMenu.php @@ -201,11 +201,6 @@ protected function loadAdmMenuVolunteer() { $treeMenu = []; $treeMenu[] = $this->addAdmMenuCollapse(); - $treeMenu[] = $this->admMenuLnk( - '/dash/volunteer', - 'Dashboard', - '' - ); $stars = ''; if (isset($GLOBALS["SL"]->x["yourUserInfo"]) && isset($GLOBALS["SL"]->x["yourUserInfo"]->UserInfoStars)) { diff --git a/src/Controllers/OpenPolicePCIF.php b/src/Controllers/OpenPolicePCIF.php new file mode 100644 index 0000000..f41a653 --- /dev/null +++ b/src/Controllers/OpenPolicePCIF.php @@ -0,0 +1,287 @@ + + * @since v0.2.17 + */ +namespace OpenPolice\Controllers; + +use DB; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Response; +use SurvLoop\Controllers\Globals\Globals; +use SurvLoop\Controllers\Tree\TreeCustomAPI; + +class OpenPolicePCIF extends OpenListing +{ + + public function printPcifSchemaType(Request $request, $type = 'xml') + { + $GLOBALS["SL"] = new Globals($request, 1, 1, 1); + $pageUrl = '/api/complaints-pcif-schema-' . $type; + $ret = $GLOBALS["SL"]->chkCache($pageUrl, 'api-cust', 1); + if (trim($ret) == '' || $request->has('refresh')) { + $this->loadPcifSchema($type); + $filename = 'complaints-pcif-schema_' . date("Ymd") . '.' . $type; + $ret = $this->v["pcif"]->returnSchema($type, $filename, $pageUrl); + $GLOBALS["SL"]->putCache($pageUrl, $ret, 'api-cust', 1); + } + if ($type == 'xml') { + return Response::make($ret, '200') + ->header('Content-Type', 'text/xml'); + } + // else $type == 'eng' + return view('vendor.survloop.master', [ "content" => $ret ])->render(); + } + + public function printPcifSchema(Request $request) + { + return $this->printPcifSchemaType($request, 'eng'); + } + + public function printPcifSchemaXml(Request $request) + { + return $this->printPcifSchemaType($request, 'xml'); + } + + public function printPcifExample(Request $request, $type = 'xml') + { + $GLOBALS["SL"] = new Globals($request, 1, 1, 1); + $this->loadPcifSchema($type); + + } + + public function printPcifAll(Request $request, $type = 'xml') + { + $this->loadPageVariation($request, 1, 1, '/api/complaints-pcif-xml'); + $GLOBALS["SL"]->pageView = 'public'; + $ret = $GLOBALS["SL"]->chkCache('/api/complaints-pcif-xml', 'api-cust', 1); + if (trim($ret) == '' || $request->has('refresh')) { + $limit = $GLOBALS["SL"]->getLimit(); + $this->loadPcifSchema($type, true); + $ret = view( + 'vendor.survloop.admin.tree.xml-header-custom', + [ "apiDesc" => $this->v["pcif"]->apiDesc ] + )->render(); + $ret .= '<' . $this->v["pcif"]->corePlural . ' xmlns="' + . $this->v["pcif"]->apiNamespace . '" xmlns:xsi="' + . $this->v["pcif"]->apiNamespace . '" xsi:schemaLocation="' + . $this->v["pcif"]->apiSchema . '" xsi:noNamespaceSchemaLocation="' + . $this->v["pcif"]->apiSchema . '">'; + $allIDs = $this->getAllPublicCoreIDs('complaints'); + if (sizeof($allIDs) > 0) { + foreach ($allIDs as $i => $coreID) { + if ($i < $limit) { + $this->coreID = $coreID; + $this->loadAllSessData('complaints', $coreID); + if (isset($this->sessData->dataSets["complaints"]) + && sizeof($this->sessData->dataSets["complaints"]) > 0) { + $pcifID = 'OP' . $this->sessData->dataSets["complaints"][0]->com_public_id; + $ret .= $this->printRecordCustomAPI('pcif', $type, $pcifID); + } + } + } + } + $ret .= 'v["pcif"]->corePlural . '>'; + $GLOBALS["SL"]->putCache('/api/complaints-pcif-xml', $ret, 'api-cust', 1); + } + return Response::make($ret, '200')->header('Content-Type', 'text/xml'); + } + + public function loadPcifSchema($type = 'xml', $opOnly = false) + { + $apiName = 'Police Complaint Interchange Format (PCIF)'; + $desc = view('vendor.openpolice.api.pcif-schema-header', [ + "type" => $type + ])->render(); + $this->v["pcif"] = new TreeCustomAPI($apiName, 'complaints', 'complaint', $desc); + $this->v["pcif"]->setSchema('https://openpolice.org/api/complaints-pcif-schema-xml'); + + $this->v["pcif"]->addTable('complaints', 'complaint', 'complaints'); + $this->v["pcif"]->addFld( + 'complaints', + 'pcif_id', + 'PCIF Complaint ID#', + 'Indicates the unique PCIF Complaint ID# for this police conduct record. ' + . 'Records sourced from Raheem.ai begin with "RA" ' + . 'and OpenPolice.org records begin with "OP". e.g. OP81, RA2397' + ); + $this->v["pcif"]->addFld( + 'complaints', + 'url', + 'Published Complaint URL', + 'Indicates the URL where this complaint record ' + . 'can be found published on the internet.' + ); + $this->v["pcif"]->addFldID('complaints', 10269); // com_anon + $this->v["pcif"]->addFldID('complaints', 245); // inc_time_start + $this->v["pcif"]->addFldID('complaints', 240); // inc_address + $this->v["pcif"]->addFldID('complaints', 805); // inc_address_city + $this->v["pcif"]->addFldID('complaints', 806); // inc_address_state + $this->v["pcif"]->addFldID('complaints', 807); // inc_address_zip + $this->v["pcif"]->addFldID('complaints', 789); // com_summary + $this->v["pcif"]->addFldID('complaints', 10292); // scn_how_feel + $this->v["pcif"]->addFldID('complaints', 10293); // scn_desires_officers + $this->v["pcif"]->addFldID('complaints', 10295); // scn_desires_depts + $this->v["pcif"]->addFldID('complaints', 1151); // com_anyone_charged + $this->v["pcif"]->addFldID('complaints', 1124); // com_all_charges_resolved + + $this->v["pcif"]->addTable('departments', 'department', 'links_complaint_dept'); + $this->v["pcif"]->addFldID('departments', 422); // dept_name + $this->v["pcif"]->addFldID('departments', 622); // dept_address_city + $this->v["pcif"]->addFldID('departments', 623); // dept_address_state + + $this->v["pcif"]->addTable('officers', 'officer', 'officers'); + $this->v["pcif"]->addFldID('officers', 397); // off_role + $this->v["pcif"]->addFldID('officers', 1006); // off_duty_status + $this->v["pcif"]->addFldID('officers', 1220); // prsn_name_first + $this->v["pcif"]->addFldID('officers', 1222); // prsn_name_last + $this->v["pcif"]->addFldID('officers', 1339); // off_badge_number + $this->v["pcif"]->addFldID('officers', 1169); // phys_race_race + $this->v["pcif"]->addFldID('officers', 628); // phys_gender + $this->v["pcif"]->addFldID('officers', 629); // phys_age + + $this->v["pcif"]->addTable('civilians', 'civilian', 'civilians'); + $this->v["pcif"]->addFldID('civilians', 990); // civ_role + $this->v["pcif"]->addFldID('civilians', 1220); // prsn_name_first + $this->v["pcif"]->addFldID('civilians', 1222); // prsn_name_last + $this->v["pcif"]->addFldID('civilians', 1169); // phys_race_race + $this->v["pcif"]->addFldID('civilians', 628); // phys_gender + $this->v["pcif"]->addFldID('civilians', 629); // phys_age + $this->v["pcif"]->addFldID('civilians', 1233); // prsn_birthday + $this->loadPcifSchemaAllegOP(); + if (!$opOnly) { + $this->loadPcifSchemaAllegRaheem(); + } + return true; + } + + // OpenPolice.org Allegations + public function loadPcifSchemaAllegOP() + { + $this->v["pcif"]->addTable('openpolice_allegations', 'openpolice_allegation', 'alleg_silver', true); + $this->v["pcif"]->addFldID('openpolice_allegations', 1093); // alle_sil_stop_wrongful + $this->v["pcif"]->addFldID('openpolice_allegations', 1095); // alle_sil_officer_refuse_id + $this->v["pcif"]->addFldID('openpolice_allegations', 1097); // alle_sil_search_wrongful + $this->v["pcif"]->addFldID('openpolice_allegations', 1099); // alle_sil_property_wrongful + $this->v["pcif"]->addFldID('openpolice_allegations', 1440); // alle_sil_property_damage + $this->v["pcif"]->addFldID('openpolice_allegations', 1399); // alle_sil_sexual_harass + $this->v["pcif"]->addFldID('openpolice_allegations', 1108); // alle_sil_sexual_assault + $this->v["pcif"]->addFldID('openpolice_allegations', 1101); // alle_sil_force_unreason + $this->v["pcif"]->addFldID('openpolice_allegations', 812); // alle_sil_intimidating_weapon + $this->v["pcif"]->addFldID('openpolice_allegations', 1103); // alle_sil_arrest_wrongful + $this->v["pcif"]->addFldID('openpolice_allegations', 1106); // alle_sil_arrest_retaliatory + $this->v["pcif"]->addFldID('openpolice_allegations', 1165); // alle_sil_citation_excessive + $this->v["pcif"]->addFldID('openpolice_allegations', 1109); // alle_sil_bias + $this->v["pcif"]->addFldID('openpolice_allegations', 1563); // alle_sil_repeat_harass + $this->v["pcif"]->addFldID('openpolice_allegations', 1117); // alle_sil_neglect_duty + $this->v["pcif"]->addFldID('openpolice_allegations', 1107); // alle_sil_procedure + $this->v["pcif"]->addFldID('openpolice_allegations', 1111); // alle_sil_unbecoming + $this->v["pcif"]->addFldID('openpolice_allegations', 1112); // alle_sil_discourteous + $this->v["pcif"]->fldNameStrReplace('alle_sil_', ''); + return true; + } + + // Raheem.ai Allegations + public function loadPcifSchemaAllegRaheem() + { + $this->v["pcif"]->addTable('raheem_allegations', 'raheem_allegation'); + $enums = [ + 'helped', 'protected', 'profiled', 'neglected', 'harassed', + 'wrongly accused', 'disrespected', 'physically attacked' + ]; + $this->v["pcif"]->addFld( + 'raheem_allegations', + 'encounter_type', + 'Type of Encounter', + 'Indicates the general type of encounter documented by this record.', + $enums + ); + $enums = [ 'Y', 'N' ]; + $this->v["pcif"]->addFld( + 'raheem_allegations', + 'force_or_weapon', + 'Use Physical Force or Point Weapon?', + 'Did police use physical force against you or point their weapon at you?', + $enums + ); + $this->v["pcif"]->addFld( + 'raheem_allegations', + 'verbal_threats', + 'Threatened Verbally or Intimidated?', + 'Did police threaten you verbally, use foul language, or intimidate you during this encounter?', + $enums + ); + $this->v["pcif"]->addFld( + 'raheem_allegations', + 'money_property', + 'Money/Property Seized/Destroyed, or Excessive Fine?', + 'Did police take money, take or destroy property, or issue an excessive fine during this encounter?', + $enums + ); + $this->v["pcif"]->addFld( + 'raheem_allegations', + 'neglect_duty', + 'Neglect of Duty?', + 'Did police fail to help you when you needed it?', + $enums + ); + return true; + } + + public function overrideRecordValueCustomAPI($name = 'custom_api', $type = 'xml', $tbl = '', $rec = null, $apiFld = null) + { + if ($name == 'pcif') { + if ($tbl == 'complaints' + && isset($this->sessData->dataSets[$tbl])) { + $id = $this->sessData->dataSets[$tbl][0]->com_public_id; + if ($apiFld->label == 'pcif_id') { + return 'OP' . $id; + } elseif ($apiFld->label == 'url') { + return 'https://openpolice.org/complaint/read-' . $id; + } + } elseif ($tbl == 'civilians' + && $apiFld->label == 'birthday' + && isset($this->sessData->dataSets[$tbl]) + && isset($rec->civ_birthday) + && trim($rec->civ_birthday) != '') { + return date("Y", strtotime($rec->civ_birthday)); + } + } + return ''; + } + + protected function genXmlFormatValCustomPerms($rec, $fld, $abbr) + { + if ($abbr == 'com_') { + if ($fld->fld_name == 'summary' + && $this->canPrintFullReportByRecordSpecs()) { + return true; + } elseif ($fld->fld_name == 'address' + && $this->canPrintIncidentLocation()) { + return true; + } + } + if ($abbr == 'off_') { + if (in_array($fld->fld_name, ['name_first', 'name_last', 'badge_number']) + && $this->canPrintOfficersName($this->sessData->dataSets["complaints"][0]) + && $this->corePublishStatuses($this->sessData->dataSets["complaints"][0])) { + return true; + } + } + if ($abbr == 'civ_') { + if (in_array($fld->fld_name, ['name_first', 'name_last']) + && $this->canPrintComplainantName($this->sessData->dataSets["complaints"][0]) + && $this->corePublishStatuses($this->sessData->dataSets["complaints"][0])) { + return true; + } + } + return false; + } + +} \ No newline at end of file diff --git a/src/Controllers/OpenPoliceUtils.php b/src/Controllers/OpenPoliceUtils.php index 14f9121..1235466 100644 --- a/src/Controllers/OpenPoliceUtils.php +++ b/src/Controllers/OpenPoliceUtils.php @@ -252,6 +252,7 @@ public function getAllPublicCoreIDs($coreTbl = '') $coreTbl = $GLOBALS["SL"]->coreTbl; } $this->allPublicCoreIDs = $list = []; + $list = null; if ($coreTbl == 'complaints') { $list = OPComplaints::whereIn('com_status', $this->getPublishedStatusList($coreTbl)) @@ -267,7 +268,7 @@ public function getAllPublicCoreIDs($coreTbl = '') ->orderBy('created_at', 'desc') ->get(); } - if ($list->isNotEmpty()) { + if ($list && $list->isNotEmpty()) { foreach ($list as $l) { $this->allPublicCoreIDs[] = $l->com_public_id; } @@ -337,13 +338,8 @@ protected function complaintHasPublishedStatus() return 0; } - protected function canPrintFullReportByRecSettings($com = null) + protected function canPrintOfficersName($com = null) { - if ( (!$com || $com === null) - && isset($this->sessData->dataSets["complaints"]) - && isset($this->sessData->dataSets["complaints"][0]) ) { - $com = $this->sessData->dataSets["complaints"][0]; - } $printOff = false; if (!isset($this->sessData->dataSets["officers"]) || sizeof($this->sessData->dataSets["officers"]) == 0) { @@ -352,9 +348,29 @@ protected function canPrintFullReportByRecSettings($com = null) && intVal($com->com_publish_officer_name) == 1) { $printOff = true; } + return $printOff; + } + + protected function canPrintComplainantName($com = null) + { return (isset($com->com_publish_user_name) - && intVal($com->com_publish_user_name) == 1 - && $printOff); + && intVal($com->com_publish_user_name) == 1); + } + + protected function canPrintFullReportByRecSettings($com = null) + { + if ( (!$com || $com === null) + && isset($this->sessData->dataSets["complaints"]) + && isset($this->sessData->dataSets["complaints"][0]) ) { + $com = $this->sessData->dataSets["complaints"][0]; + } + return ($this->canPrintComplainantName($com) + && $this->canPrintOfficersName($com)); + } + + protected function corePublishStatuses($com = null) + { + return in_array($com->com_status, [200, 201, 203, 204]); } protected function canPrintFullReportByRecordSpecs($com = null) @@ -364,7 +380,7 @@ protected function canPrintFullReportByRecordSpecs($com = null) && isset($this->sessData->dataSets["complaints"][0]) ) { $com = $this->sessData->dataSets["complaints"][0]; } - return (in_array($com->com_status, [200, 201, 203, 204]) + return ($this->corePublishStatuses($com) && $this->canPrintFullReportByRecSettings($com)); } @@ -407,6 +423,11 @@ protected function maxUserView() if (isset($GLOBALS["fullAccess"]) && $GLOBALS["fullAccess"]) { $GLOBALS["SL"]->pageView = 'full'; } + } elseif (isset($this->sessData->dataSets["complaints"]) + && $this->v["uID"] == $this->sessData->dataSets["complaints"][0]->com_user_id) { + if (isset($GLOBALS["fullAccess"]) && $GLOBALS["fullAccess"]) { + $GLOBALS["SL"]->pageView = 'full'; + } } elseif ($this->v["user"]->hasRole('administrator|staff')) { $GLOBALS["SL"]->pageView = 'full'; } elseif ($this->v["user"]->hasRole('partner') diff --git a/src/Controllers/OpenReport.php b/src/Controllers/OpenReport.php index 9851075..7dc26c6 100644 --- a/src/Controllers/OpenReport.php +++ b/src/Controllers/OpenReport.php @@ -13,8 +13,8 @@ use DB; use Auth; use App\Models\OPDepartments; -use App\Models\OPZeditDepartments; -use App\Models\OPZeditOversight; +use App\Models\OPzEditDepartments; +use App\Models\OPzEditOversight; use App\Models\OPzVolunTmp; use App\Models\OPOversight; use OpenPolice\Controllers\OpenOfficers; @@ -96,9 +96,9 @@ protected function reportAllegsWhy($nID = -3) } $deets .= '

'; if ($fullPrint) { - return $this->printReportDeetsBlock($why, $deets); + return $this->printReportDeetsBlock($why, $deets, $this->allNodes[$nID]); } - return $this->printReportDeetsBlockCols($why, $deets); + return $this->printReportDeetsBlockCols($why, $deets, 2, $this->allNodes[$nID]); } /** @@ -225,12 +225,16 @@ protected function getReportDept($deptID) { $dept = $this->sessData->getRowById('departments', $deptID); if ($dept && isset($dept->dept_name)) { + $extra = ''; + if ($dept->dept_name == 'Not sure about department') { + $extra = ''; + } return '

' . 'Misconduct Incident Report for ' . $dept->dept_name . '

' . '
Complaint #' . $this->sessData->dataSets["complaints"][0]->com_public_id . ': ' . $this->printComplaintStatus($this->sessData->dataSets["complaints"][0]->com_status) - . '
'; + . '' . $extra; } $this->v["reportDepts"][] = $deptID; return ''; @@ -295,10 +299,10 @@ protected function getReportWhenLine() $date = date('n/j/Y', strtotime($inc->inc_time_start)); $timeStart = $timeEnd = ''; if ($inc->inc_time_end !== null) { - $timeEnd = date('g:ia', strtotime($inc->inc_time_end)); + $timeEnd = date('g:i a', strtotime($inc->inc_time_end)); } if ($inc->inc_time_start !== null) { - $timeStart = date('g:ia', strtotime($inc->inc_time_start)); + $timeStart = date('g:i a', strtotime($inc->inc_time_start)); $date .= $this->printStartEndTimes($timeStart, $timeEnd); } } else { @@ -319,7 +323,7 @@ protected function printStartEndTimes($timeStart, $timeEnd) { $ret = ''; if ($timeStart != '' - && ($timeStart != '12:00am' || $timeStart != $timeEnd)) { + && ($timeStart != '12:00 am' || $timeStart != $timeEnd)) { $ret .= ' at ' . $timeStart . ''; if ($timeEnd != '' && $timeStart != $timeEnd) { $ret .= ' until ' . $timeEnd . ''; @@ -723,6 +727,56 @@ protected function getOffNickname($off, $ind = 0, $prsn = NULL) } return ''; } + + /** + * Print the Civilian name tied to this Use of Force. + * + * @return string + */ + protected function getForceCivName() + { + $ret = ''; + $forceID = $this->sessData->getLatestDataBranchID(); + if ($forceID > 0 + && isset($this->sessData->dataSets["links_civilian_force"]) + && sizeof($this->sessData->dataSets["links_civilian_force"]) > 0) { + foreach ($this->sessData->dataSets["links_civilian_force"] as $lnk) { + if (isset($lnk->lnk_civ_frc_force_id) + && $lnk->lnk_civ_frc_force_id == $forceID) { + $ret .= ', ' . $this->getCivReportName($lnk->lnk_civ_frc_civ_id); + } + } + if ($ret != '') { + $ret = substr($ret, 1); + } + } + return $ret; + } + + /** + * Print the Officer name tied to this Use of Force. + * + * @return string + */ + protected function getForceOffName() + { + $ret = ''; + $forceID = $this->sessData->getLatestDataBranchID(); + if ($forceID > 0 + && isset($this->sessData->dataSets["links_officer_force"]) + && sizeof($this->sessData->dataSets["links_officer_force"]) > 0) { + foreach ($this->sessData->dataSets["links_officer_force"] as $lnk) { + if (isset($lnk->lnk_off_frc_force_id) + && $lnk->lnk_off_frc_force_id == $forceID) { + $ret .= ', ' . $this->getOffReportName($lnk->lnk_off_frc_off_id); + } + } + if ($ret != '') { + $ret = substr($ret, 1); + } + } + return $ret; + } /** * Create a list of civilian information fields which are not to be printed @@ -988,12 +1042,17 @@ protected function printFlexVids() * * @param int $nID * @param string $val + * @param App\Models\SLFields $fldRow * @return string */ - protected function printValCustom($nID, $val) + protected function printValCustom($nID, $val, $fldRow) { if (in_array($nID, [1486, 1528])) { return $GLOBALS["SL"]->printHeight(intVal($val)); + } elseif ($nID == 2834) { + return $this->getForceCivName(); + } elseif ($nID == 2835) { + return $this->getForceOffName(); } return $val; } diff --git a/src/Controllers/OpenReportTools.php b/src/Controllers/OpenReportTools.php index 16ca802..c50ae89 100644 --- a/src/Controllers/OpenReportTools.php +++ b/src/Controllers/OpenReportTools.php @@ -128,11 +128,15 @@ protected function printComplaintOwnerPrivacyForm() 'Declined To Investigate (Closed)', 'Investigated (Closed)' ]; + $offCnt = 0; + if (isset($this->sessData->dataSets["officers"])) { + $offCnt = sizeof($this->sessData->dataSets["officers"]); + } return view( 'vendor.openpolice.inc-static-privacy-page', [ "complaint" => $this->sessData->dataSets["complaints"][0], - "offCnt" => sizeof($this->sessData->dataSets["officers"]), + "offCnt" => $offCnt, "twoOptions" => in_array($status, $tooLateForAnon) ] )->render(); @@ -217,7 +221,8 @@ protected function processOwnerUpdateStatus() $evalNotes .= $this->processComplaintOwnerStatus(); $this->logComplaintReview('Owner', $evalNotes, $GLOBALS["SL"]->REQ->overStatus); - if ($GLOBALS["SL"]->REQ->has('overStatus')) { + if ($GLOBALS["SL"]->REQ->has('overStatus') + && trim($GLOBALS["SL"]->REQ->overStatus) != '') { $defSet = 'Complaint Status'; $okdDef = $GLOBALS["SL"]->def->getID($defSet, 'OK to Submit to Oversight'); $subDef = $GLOBALS["SL"]->def->getID($defSet, 'Submitted to Oversight'); @@ -314,24 +319,29 @@ protected function processComplaintOverDates() $newDate = $GLOBALS["SL"]->dateToTime($newDate); } if ($oldDate != $newDate) { - if (intVal($newDate) > 0) { - $this->v["comDepts"][$c]["overDates"]->update([ - $dbFld => date("Y-m-d", $newDate) . ' 00:00:00' - ]); + if (!isset($this->v["comDepts"][$c]["overDates"]->lnk_com_over_dept_id)) { + $evalNotes .= '
Failed to save update on department #' + . $dept["id"] . '.
'; } else { - $this->v["comDepts"][$c]["overDates"]->update([ - $dbFld => NULL - ]); + if (intVal($newDate) > 0) { + $this->v["comDepts"][$c]["overDates"]->update([ + $dbFld => date("Y-m-d", $newDate) . ' 00:00:00' + ]); + } else { + $this->v["comDepts"][$c]["overDates"]->update([ + $dbFld => NULL + ]); + } + $evalNotes .= view( + 'vendor.openpolice.nodes.1712-report-inc-date-eval-note', + [ + "deptName" => $dept["deptRow"]->dept_name, + "dateLabel" => $this->v["oversightDateLookups"][$d][1], + "oldDate" => $oldDate, + "newDate" => $newDate + ] + )->render(); } - $evalNotes .= view( - 'vendor.openpolice.nodes.1712-report-inc-date-eval-note', - [ - "deptName" => $dept["deptRow"]->dept_name, - "dateLabel" => $this->v["oversightDateLookups"][$d][1], - "oldDate" => $oldDate, - "newDate" => $newDate - ] - )->render(); } } } diff --git a/src/Controllers/OpenReportToolsAdmin.php b/src/Controllers/OpenReportToolsAdmin.php index 7858546..7285e22 100644 --- a/src/Controllers/OpenReportToolsAdmin.php +++ b/src/Controllers/OpenReportToolsAdmin.php @@ -595,8 +595,7 @@ protected function processComplaintFixDepts() $status = $GLOBALS["SL"]->def->getVal('Complaint Status', $status); $this->logComplaintReview('Staff', $evalNotes, $status); $this->fixDeptsClean(); - $redir = '/complaint/read-' . $this->corePublicID - . '?refresh=1' . $GLOBALS['SL']->getReqParams(); + $redir = '/dash/complaint/read-' . $this->corePublicID . '?refresh=1'; $this->redir($redir, true); exit; } diff --git a/src/Controllers/OpenSessDataOverride.php b/src/Controllers/OpenSessDataOverride.php index ba6946f..3205bf5 100644 --- a/src/Controllers/OpenSessDataOverride.php +++ b/src/Controllers/OpenSessDataOverride.php @@ -60,9 +60,11 @@ protected function printNodeSessDataOverride(&$curr) } } elseif ($nID == 671) { // Officers Used Profanity? $currVals = []; - foreach ($this->sessData->dataSets["officers"] as $i => $off) { - if (isset($off->off_used_profanity) && $off->off_used_profanity == 'Y') { - $currVals[] = $off->getKey(); + if (isset($this->sessData->dataSets["officers"])) { + foreach ($this->sessData->dataSets["officers"] as $i => $off) { + if (isset($off->off_used_profanity) && $off->off_used_profanity == 'Y') { + $currVals[] = $off->getKey(); + } } } return [';' . implode(';', $currVals) . ';']; @@ -199,7 +201,7 @@ protected function printNodeSessDataOverrideWays2() } if (isset($this->v["overRowIA"]->over_way_sub_notary) && intVal($this->v["overRowIA"]->over_way_sub_notary) > 0) { - $sessData[] = 'way_sub_notary'; + $sessData[] = 'notary'; } if (isset($this->v["overRowIA"]->over_submit_deadline) && intVal($this->v["overRowIA"]->over_submit_deadline) > 0) { diff --git a/src/Controllers/OpenVolunteers.php b/src/Controllers/OpenVolunteers.php index 8931323..b5bb970 100644 --- a/src/Controllers/OpenVolunteers.php +++ b/src/Controllers/OpenVolunteers.php @@ -12,9 +12,12 @@ use DB; use Illuminate\Http\Request; +use App\Models\User; use App\Models\OPPartners; use App\Models\OPDepartments; -use App\Models\OPZeditDepartments; +use App\Models\OPzEditDepartments; +use App\Models\SLSess; +use App\Models\SLSessPage; use OpenPolice\Controllers\VolunteerLeaderboard; use OpenPolice\Controllers\OpenDevelopment; @@ -63,7 +66,7 @@ public function chkVolunInitLists() $this->v["searchForm"] = $this->deptSearchForm(); $orderby = [ [ 'dept_verified', 'desc' ], - [ 'dept_name', 'asc' ] + [ 'dept_name', 'asc' ] ]; switch ($this->v["viewType"]) { case 'best': @@ -75,7 +78,7 @@ public function chkVolunInitLists() case 'city': $orderby = [ [ 'dept_address_state', 'asc' ], - [ 'dept_address_city', 'asc' ] + [ 'dept_address_city', 'asc' ] ]; break; } @@ -86,11 +89,19 @@ public function chkVolunInitLists() && trim($this->v["yourContact"]->prsn_address_state) != '') { $this->v["state"] = trim($this->v["yourContact"]->prsn_address_state); } - if ($GLOBALS["SL"]->REQ->has('s') && trim($GLOBALS["SL"]->REQ->get('s')) != '') { + $fedDef = $GLOBALS["SL"]->def->getID( + 'Department Types', + 'Federal Law Enforcement' + ); + if ($GLOBALS["SL"]->REQ->has('s') + && trim($GLOBALS["SL"]->REQ->get('s')) != '') { $this->chkRecsPub($GLOBALS["SL"]->REQ, 36); $searches = []; - if ($GLOBALS["SL"]->REQ->has('s') && trim($GLOBALS["SL"]->REQ->get('s')) != '') { - $searches = $GLOBALS["SL"]->parseSearchWords($GLOBALS["SL"]->REQ->get('s')); + if ($GLOBALS["SL"]->REQ->has('s') + && trim($GLOBALS["SL"]->REQ->get('s')) != '') { + $searches = $GLOBALS["SL"]->parseSearchWords( + $GLOBALS["SL"]->REQ->get('s') + ); } if (sizeof($searches) > 0) { $rows = null; @@ -108,37 +119,70 @@ public function chkVolunInitLists() $GLOBALS["SL"]->addSrchResults('depts', $rows, 'dept_id'); } } else { - foreach ($searches as $s) { - $sP = '%' . $s . '%'; - $rows = OPDepartments::where('dept_address_state', $this->v["state"]) - ->where(function ($query) use ($s) { - $query->where('dept_name', 'LIKE', $sP) - ->orWhere('dept_email', 'LIKE', $sP) - ->orWhere('dept_phone_work', 'LIKE', $sP) - ->orWhere('dept_address', 'LIKE', $sP) - ->orWhere('dept_address_city', 'LIKE', $sP) - ->orWhere('dept_address_zip', 'LIKE', $sP) - ->orWhere('dept_address_county', 'LIKE', $sP); - }) - ->get(); - $GLOBALS["SL"]->addSrchResults('depts', $rows, 'dept_id'); + if ($this->v["state"] == 'US') { + foreach ($searches as $s) { + $sP = '%' . $s . '%'; + $rows = OPDepartments::where('dept_type', $fedDef) + ->where(function ($query) use ($sP) { + $query->where('dept_name', 'LIKE', $sP) + ->orWhere('dept_email', 'LIKE', $sP) + ->orWhere('dept_phone_work', 'LIKE', $sP) + ->orWhere('dept_address', 'LIKE', $sP) + ->orWhere('dept_address_city', 'LIKE', $sP) + ->orWhere('dept_address_zip', 'LIKE', $sP) + ->orWhere('dept_address_county', 'LIKE', $sP); + }) + ->get(); + $GLOBALS["SL"]->addSrchResults('depts', $rows, 'dept_id'); + } + } else { + foreach ($searches as $s) { + $sP = '%' . $s . '%'; + $rows = OPDepartments::where('dept_type', 'NOT LIKE', $fedDef) + ->where('dept_address_state', $this->v["state"]) + ->where(function ($query) use ($sP) { + $query->where('dept_name', 'LIKE', $sP) + ->orWhere('dept_email', 'LIKE', $sP) + ->orWhere('dept_phone_work', 'LIKE', $sP) + ->orWhere('dept_address', 'LIKE', $sP) + ->orWhere('dept_address_city', 'LIKE', $sP) + ->orWhere('dept_address_zip', 'LIKE', $sP) + ->orWhere('dept_address_county', 'LIKE', $sP); + }) + ->get(); + $GLOBALS["SL"]->addSrchResults('depts', $rows, 'dept_id'); + } } } } $this->v["deptRows"] = $GLOBALS["SL"]->x["srchRes"]["depts"]; unset($GLOBALS["SL"]->x["srchRes"]["depts"]); } elseif ($this->v["state"] != '') { - $this->v["deptRows"] = OPDepartments::where('dept_address_state', $this->v["state"]) - ->select('dept_id', 'dept_name', 'dept_score_openness', - 'dept_verified', 'dept_address_city', 'dept_address_state') - ->orderBy($orderby[0][0], $orderby[0][1]) - ->get(); + if ($this->v["state"] == 'US') { + $this->v["deptRows"] = OPDepartments::where('dept_type', $fedDef) + ->select('dept_id', 'dept_name', 'dept_score_openness', + 'dept_verified', 'dept_address_city', 'dept_address_state') + ->orderBy($orderby[0][0], $orderby[0][1]) + ->get(); + } else { + $this->v["deptRows"] = OPDepartments::where('dept_address_state', $this->v["state"]) + ->where('dept_type', 'NOT LIKE', $fedDef) + ->select('dept_id', 'dept_name', 'dept_score_openness', + 'dept_verified', 'dept_address_city', 'dept_address_state') + ->orderBy($orderby[0][0], $orderby[0][1]) + ->get(); + } } else { $this->v["deptRows"] = OPDepartments::select('dept_id', 'dept_name', 'dept_score_openness', 'dept_verified', 'dept_address_city', 'dept_address_state') ->orderBy($orderby[0][0], $orderby[0][1]) ->get(); } + if ($this->v["deptRows"] && sizeof($this->v["deptRows"]) > 0) { + foreach ($this->v["deptRows"] as $dept) { + $this->isDeptBeingEdited($dept->dept_id); + } + } $this->loadRecentDeptEdits(); $GLOBALS["SL"]->loadStates(); } @@ -187,7 +231,11 @@ public function printVolunAllList() protected function loadDeptPriorityRows() { $this->v["deptPriorityRows"] = $done = $rejects = []; - $this->v["yearold"] = mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y")-1); + $this->v["yearold"] = mktime(date("H"), date("i"), date("s"), + date("m")-18, date("d"), date("Y")); + $this->v["twomonths"] = mktime( + date("H"), date("i"), date("s"), date("m")-2, date("d"), date("Y") + ); $set = 'Complaint Status'; $statuses = [ $GLOBALS["SL"]->def->getID($set, 'New'), @@ -208,18 +256,23 @@ protected function loadDeptPriorityRows() '=', 'op_links_complaint_dept.lnk_com_dept_dept_id') ->join('op_complaints', 'op_links_complaint_dept.lnk_com_dept_complaint_id', '=', 'op_complaints.com_id') + //->where('op_departments.dept_name', 'NOT LIKE', 'Not sure about department') ->whereIn('op_complaints.com_type', $types) ->whereIn('op_complaints.com_status', $statuses) ->where('op_complaints.com_summary', 'NOT LIKE', '') - ->select('op_departments.*') + //->where('op_complaints.created_at', '>', date("Y-m-d", $this->v["twomonths"])) + ->select('op_departments.*', 'op_complaints.created_at') ->orderBy('op_complaints.created_at', 'asc') ->get(); if ($chk->isNotEmpty()) { foreach ($chk as $dept) { +//echo 'um? ' . $dept->dept_name . ', ' . $dept->created_at . ' is ' . strtotime($dept->created_at) . ' ? > ' . $this->v["twomonths"] . '
'; if (!in_array($dept->dept_id, $done) + && strtotime($dept->created_at) > $this->v["twomonths"] && (!isset($dept->dept_score_openness) || !isset($dept->dept_verified) - || $dept->dept_verified < date("Y-m-d H:i:s", $this->v["yearold"]))) { + || strtotime($dept->dept_verified) < $this->v["yearold"])) { + $this->isDeptBeingEdited($dept->dept_id); $this->v["deptPriorityRows"][] = $dept; $done[] = $dept->dept_id; } else { @@ -227,10 +280,79 @@ protected function loadDeptPriorityRows() } } } -//echo 'done:
'; print_r($done); echo '
rejects:
'; print_r($rejects); echo '
'; exit; +//echo 'priority:
'; print_r($this->v["deptPriorityRows"]); print_r($chk); echo '
'; exit; return $this->v["deptPriorityRows"]; } + /** + * Prepare the list of departments which need most urgent help with research. + * + * @return boolean + */ + protected function isDeptBeingEdited($deptID) + { + if ($deptID <= 0) { + return ''; + } + if (!isset($GLOBALS["SL"]->x["deptEditing"])) { + $GLOBALS["SL"]->x["deptEditing"] = []; + } + if (!isset($GLOBALS["SL"]->x["deptEditing"][$deptID])) { + $GLOBALS["SL"]->x["deptEditing"][$deptID] = ''; + $this->v["twohrs"] = mktime( + date("H")-2, date("i"), date("s"), date("m"), date("d"), date("Y") + ); + $chk = SLSess::where('sess_tree', 36) + ->where('sess_core_id', $deptID) + ->where('sess_is_active', 1) + ->where('sess_user_id', 'NOT LIKE', $this->v["uID"]) + ->orderBy('updated_at', 'desc') + ->get(); + if ($chk->isNotEmpty()) { + foreach ($chk as $sess) { +//echo '
'; print_r($sess); echo '
'; + $editing = 0; + if ($this->v["twohrs"] < strtotime($sess->updated_at)) { + $editing = strtotime($sess->updated_at); +//echo 'A editing: ' . $editing . '
'; + } else { + $save = SLSessPage::where('sess_page_sess_id', $sess->sess_id) + ->where('updated_at', '>', date("Y-m-d H:i:s", $this->v["twohrs"])) + ->first(); + if ($save && isset($save->sess_page_id)) { + if ($editing < strtotime($save->updated_at)) { + $editing = strtotime($save->updated_at); +//echo 'B editing: ' . $editing . '
'; + } + } + } +//echo 'C editing: ' . $editing . '
'; + // check for completion since latest timestamp + if ($editing > 0) { + $edit = OPzEditDepartments::where('zed_dept_dept_id', $deptID) + ->where('zed_dept_user_id', $chk->sess_user_id) + ->first(); + if ($edit + && isset($edit->created_at) + && $editing < strtotime($edit->created_at)) { + $editing = 0; +//echo 'D editing: ' . $editing . '
'; + } + } + // if still presumed editing, then lock it in + if ($editing > 0) { + $u = User::find($chk->sess_user_id); + if ($u) { + $GLOBALS["SL"]->x["deptEditing"][$deptID] = $u->printUsername(); + } + } +//exit; + } + } + } + return $GLOBALS["SL"]->x["deptEditing"][$deptID]; + } + /** * Print the shorm form for volunteers and staff to filter the list * of 18,000 police departments. @@ -263,25 +385,25 @@ protected function loadRecentDeptEdits() $GLOBALS["SL"]->x["usernames"] = []; } $GLOBALS["SL"]->x["recentDeptEdits"] = []; - $cutoff = mktime(date("H"), date("i"), date("s"), date("n"), date("j")-7, date("Y")); + $cutoff = mktime(date("H"), date("i"), date("s"), date("n")-1, date("j"), date("Y")); $cutoff = date("Y-m-d H:i:s", $cutoff); - $rows = OPZeditDepartments::where('op_z_edit_departments.zed_dept_dept_verified', '>', $cutoff) - ->leftJoin('users', 'users.id', '=', 'op_z_edit_departments.zed_dept_user_id') - ->select('op_z_edit_departments.zed_dept_dept_id', - 'op_z_edit_departments.zed_dept_dept_verified', 'users.id', 'users.name') + //where('op_z_edit_departments.zed_dept_dept_verified', '>', $cutoff) + $rows = OPzEditDepartments::leftJoin('users', 'users.id', + '=', 'op_z_edit_departments.zed_dept_user_id') + ->select('op_z_edit_departments.zed_dept_dept_id', 'users.id', + 'op_z_edit_departments.zed_dept_dept_verified', 'users.name') ->orderBy('op_z_edit_departments.zed_dept_dept_verified', 'desc') ->get(); if ($rows->isNotEmpty()) { foreach ($rows as $row) { if (!isset($GLOBALS["SL"]->x["recentDeptEdits"][$row->zed_dept_dept_id])) { - $GLOBALS["SL"]->x["recentDeptEdits"][$row->zed_dept_dept_id] = []; - } - if (!isset($GLOBALS["SL"]->x["recentDeptEdits"][$row->zed_dept_dept_id][$row->id])) { - $GLOBALS["SL"]->x["recentDeptEdits"][$row->zed_dept_dept_id][$row->id] - = $row->zed_dept_dept_verified; - } - if (!isset($GLOBALS["SL"]->x["usernames"][$row->id])) { - $GLOBALS["SL"]->x["usernames"][$row->id] = $row->name; + $GLOBALS["SL"]->x["recentDeptEdits"][$row->zed_dept_dept_id] = $row->id; + if (!isset($GLOBALS["SL"]->x["usernames"][$row->id])) { + $usr = User::find($row->id); + if ($usr) { + $GLOBALS["SL"]->x["usernames"][$row->id] = $usr->printUsername(); + } + } } } } diff --git a/src/Models/OPZeditDepartments.php b/src/Models/OPZeditDepartments.php index 9827e24..3d2f2fe 100644 --- a/src/Models/OPZeditDepartments.php +++ b/src/Models/OPZeditDepartments.php @@ -3,7 +3,7 @@ use Illuminate\Database\Eloquent\Model; -class OPZEditDepartments extends Model +class OPzEditDepartments extends Model { protected $table = 'op_z_edit_departments'; protected $primaryKey = 'zed_dept_id'; @@ -39,6 +39,7 @@ class OPZEditDepartments extends Model 'zed_dept_dept_is_mobile', 'zed_dept_dept_address_lat', 'zed_dept_dept_address_lng', + 'zed_dept_dept_op_compliant', ]; // END SurvLoop auto-generated portion of Model diff --git a/src/Models/OPZeditOversight.php b/src/Models/OPZeditOversight.php index 3f91db2..afab903 100644 --- a/src/Models/OPZeditOversight.php +++ b/src/Models/OPZeditOversight.php @@ -3,7 +3,7 @@ use Illuminate\Database\Eloquent\Model; -class OPZEditOversight extends Model +class OPzEditOversight extends Model { protected $table = 'op_z_edit_oversight'; protected $primaryKey = 'zed_over_id'; diff --git a/src/Models/OPzComplaintReviews.php b/src/Models/OPzComplaintReviews.php index b62c87f..1435256 100644 --- a/src/Models/OPzComplaintReviews.php +++ b/src/Models/OPzComplaintReviews.php @@ -3,7 +3,7 @@ use Illuminate\Database\Eloquent\Model; -class OPZComplaintReviews extends Model +class OPzComplaintReviews extends Model { protected $table = 'op_z_complaint_reviews'; protected $primaryKey = 'com_rev_id'; diff --git a/src/Models/OPzVolunStatDays.php b/src/Models/OPzVolunStatDays.php index d2be9f4..ffa19de 100644 --- a/src/Models/OPzVolunStatDays.php +++ b/src/Models/OPzVolunStatDays.php @@ -3,7 +3,7 @@ use Illuminate\Database\Eloquent\Model; -class OPZVolunStatDays extends Model +class OPzVolunStatDays extends Model { protected $table = 'op_z_volun_stat_days'; protected $primaryKey = 'volun_stat_id'; diff --git a/src/Models/OPzVolunUserInfo.php b/src/Models/OPzVolunUserInfo.php index 9ca77d6..76030ec 100644 --- a/src/Models/OPzVolunUserInfo.php +++ b/src/Models/OPzVolunUserInfo.php @@ -3,7 +3,7 @@ use Illuminate\Database\Eloquent\Model; -class OPZVolunUserInfo extends Model +class OPzVolunUserInfo extends Model { protected $table = 'op_z_volun_user_info'; protected $primaryKey = 'user_info_id'; diff --git a/src/Uploads/screenshot-protip-bottom-nav-jump.jpg b/src/Uploads/screenshot-protip-bottom-nav-jump.jpg deleted file mode 100644 index c995e8cf0569db6bc44cd2f45c1bfb6c0cc9a1ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6586 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 diff --git a/src/Views/ajax/search-police-dept.blade.php b/src/Views/ajax/search-police-dept.blade.php index 31813f8..dc23461 100755 --- a/src/Views/ajax/search-police-dept.blade.php +++ b/src/Views/ajax/search-police-dept.blade.php @@ -5,7 +5,10 @@ diff --git a/src/Views/api/pcif-schema-header.blade.php b/src/Views/api/pcif-schema-header.blade.php new file mode 100644 index 0000000..eae4bd0 --- /dev/null +++ b/src/Views/api/pcif-schema-header.blade.php @@ -0,0 +1,14 @@ +

Police Complaint Interchange Format (PCIF) is a data format +for exchanging civilian reports of negative encounters with +law enforcement entities. PCIF allows a report to be consistently +collected and disseminated across diverse systems and jurisdictions, +including among and between criminal justice advocacy organizations, +civilian police oversight groups, academics, law enforcement agencies, +and private enterprise (such as insurance companies). +

+PCIF is currently available as an XML-based export option on +OpenPolice.org, and will soon also be available in JSON. It will +soon also be available for export on Raheem.ai. We welcome your +collaboration in developing these open standards. +

+ PCIF XML Schema: openpolice.org/api/complaints-pcif-schema-xml

\ No newline at end of file diff --git a/src/Views/dept-page-filing-instructs-file-btn.blade.php b/src/Views/dept-page-filing-instructs-file-btn.blade.php index 3b586db..7de4dfe 100644 --- a/src/Views/dept-page-filing-instructs-file-btn.blade.php +++ b/src/Views/dept-page-filing-instructs-file-btn.blade.php @@ -1,18 +1,22 @@ - -dept_slug }}" -*/ ?> - + diff --git a/src/Views/dept-page-filing-instructs.blade.php b/src/Views/dept-page-filing-instructs.blade.php index 36203f6..4fc1b7e 100644 --- a/src/Views/dept-page-filing-instructs.blade.php +++ b/src/Views/dept-page-filing-instructs.blade.php @@ -180,12 +180,20 @@ Regardless, we recommend you print and send your paper complaint to the department by USPS Certified Mail. + target="_blank">USPS Certified Mail. When you get confirmation of receipt, please login to your account to let us know.

+@elseif ($d["editCnt"] == 0) + +
+ We don't yet have information about this + department's complaint policies and procedures. + Please volunteer to update this record. +
+ @else
    diff --git a/src/Views/nodes/1211-volun-home-all-depts.blade.php b/src/Views/nodes/1211-volun-home-all-depts.blade.php index e5a5849..0936c71 100644 --- a/src/Views/nodes/1211-volun-home-all-depts.blade.php +++ b/src/Views/nodes/1211-volun-home-all-depts.blade.php @@ -20,15 +20,20 @@ class="form-control slTab" {!! $GLOBALS["SL"]->tabInd() !!}
    Sort by
    - tabInd() !!} onChange="return runVolunDeptSearch();"> - - - -
    @@ -38,7 +43,7 @@ class="form-control slTab" {!! $GLOBALS["SL"]->tabInd() !!}
    -@if (sizeof($deptPriorityRows) > 0) +@if (sizeof($deptRows) > 0) {!! view( 'vendor.openpolice.volun.dept-rows', [ "deptRows" => $deptRows ] @@ -52,8 +57,11 @@ class="form-control slTab" {!! $GLOBALS["SL"]->tabInd() !!} Need to add a new police department to the database?

function fillResultCnt() { document.getElementById("searchFoundCnt").innerHTML={!! - json_encode($complaintFiltDescPrev) + json_encode('' . $complaintFiltDescPrev . '') !!}; return true; } diff --git a/src/Views/nodes/1712-report-inc-history.blade.php b/src/Views/nodes/1712-report-inc-history.blade.php index e59ebf8..0c01f17 100755 --- a/src/Views/nodes/1712-report-inc-history.blade.php +++ b/src/Views/nodes/1712-report-inc-history.blade.php @@ -11,7 +11,7 @@ @if (trim($h["desc"]) != '')
@endif {!! str_replace("\n", "
", $h["note"]) !!} @endif -
{{ date("n/j/y g:ia", $h["date"]) }} by {!! $h["who"] !!} +
{{ date("n/j/y g:i a", $h["date"]) }} by {!! $h["who"] !!}

@endforeach @else diff --git a/src/Views/nodes/1712-report-inc-staff-tools-first-review.blade.php b/src/Views/nodes/1712-report-inc-staff-tools-first-review.blade.php index 9fbd694..c949018 100644 --- a/src/Views/nodes/1712-report-inc-staff-tools-first-review.blade.php +++ b/src/Views/nodes/1712-report-inc-staff-tools-first-review.blade.php @@ -26,14 +26,14 @@ class="nCbox1712 slTab slNodeChange ntrStp n1712fldCls" data-nid="1712" autocomplete="off" tabindex="1">
Police Complaint -