Moving to GitHub.
[platal.git] / classes / jobterms.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2014 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22 class JobTerms {
23
24 const ALL = 'all';
25 const ONLY_JOBS = 'jobs';
26 const ONLY_MENTORS = 'mentors';
27
28 /** Retreives subterms of a term to display in a tree
29 * @param $parent_jtid the id of the parent jobterm
30 * @param $filter enable filtering on jobterms that have been used in jobs or in mentors, in
31 * that case, each row as an 'nb' field that counts all profiles that match
32 * @param $token_filter a text (usually ending by %) the retreived subterms to jobterms that
33 * contains this tokens or that one of their children contains it.
34 * @return an iterator over jobterms with jtid, name, full_name and nb
35 */
36 static public function getSubTerms($parent_jtid, $filter = self::ALL, $token_filter = null) {
37 switch ($filter) {
38 case self::ALL:
39 default:
40 $table = '';
41 break;
42 case self::ONLY_JOBS:
43 $table = 'profile_job_term';
44 break;
45 case self::ONLY_MENTORS:
46 $table = 'profile_mentor_term';
47 break;
48 }
49 // we are in a tree looking for certain job terms:
50 $countingterms = false;
51 if ($table) {
52 $count = ', COUNT(DISTINCT j.pid) AS nb';
53 $join = ' INNER JOIN profile_job_term_relation AS r2 ON (r2.jtid_1 = e.jtid)
54 INNER JOIN '.$table.' AS j ON (j.jtid = r2.jtid_2)';
55 $countingterms = 'j.jtid';
56 } else {
57 $count = $join = '';
58 }
59 if (!empty($token_filter)) {
60 $join .= ' INNER JOIN profile_job_term_relation AS rtf ON (rtf.jtid_1 = e.jtid) '.
61 self::token_join_query(self::tokenize($token_filter), 'rtf', 'jtid_2');
62 if (!$countingterms) {
63 $countingterms = 'rtf.jtid_2';
64 }
65 }
66 if (!$countingterms) {
67 $select_leaf = 'IF(r_subbranch.jtid_1 IS NULL,1,0)';
68 $join .= ' LEFT JOIN profile_job_term_relation AS r_subbranch ON (r_subbranch.jtid_1 = e.jtid AND r_subbranch.computed = "original") ';
69 } else {
70 // branches that have counting terms different that
71 // main branch will have subbranches
72 $select_leaf = 'MIN('.$countingterms.' = e.jtid)';
73 }
74 return XDB::iterator('SELECT e.jtid, e.name, e.full_name'.$count.', '.$select_leaf.' AS leaf
75 FROM profile_job_term_enum AS e
76 INNER JOIN profile_job_term_relation AS r ON (r.jtid_2 = e.jtid)'.$join.'
77 WHERE r.jtid_1 = {?} AND r.computed = "original"
78 GROUP BY e.jtid
79 ORDER BY e.name',
80 $parent_jtid);
81 }
82
83 /**
84 * Display a JSon page containing the sub-branches of a branch in the job terms tree.
85 * @param $page the Platal page
86 * @param $filter filter helps to display only jobterms that are contained in jobs or in mentors
87 *
88 * @param Env::i('jtid') job term id of the parent branch, if none trunk will be used
89 * @param Env::v('attrfunc') the name of a javascript function that will be called when a branch
90 * is chosen
91 * @param Env::v('treeid') tree id that will be given as first argument of attrfunc function
92 * the second argument will be the chosen job term id and the third one the chosen job's full name.
93 * @param Env::v('text_filter') a string (usually ending by %) that will be used to filter
94 * subbranches, keeping only the one containing this text in its title or in the title of one of
95 * its subbranches.
96 */
97 static public function ajaxGetBranch($page, $filter = self::ALL) {
98 pl_content_headers('application/json');
99 $page->changeTpl('include/jobterms.branch.tpl', NO_SKIN);
100 $subTerms = self::getSubTerms(Env::v('jtid'), $filter, Env::v('text_filter'));
101 $page->assign('subTerms', $subTerms);
102 switch ($filter) {
103 case self::ONLY_JOBS:
104 $page->assign('filter', 'camarade');
105 break;
106 case self::ONLY_MENTORS:
107 $page->assign('filter', 'mentor');
108 break;
109 }
110 $page->assign('jtid', Env::v('jtid'));
111 $page->assign('text_filter', Env::v('text_filter'));
112 $page->assign('attrfunc', Env::v('attrfunc'));
113 $page->assign('treeid', Env::v('treeid'));
114 }
115
116 static public function jsAddTree($platalpage, $domElement = '.term_tree', $treeid = '', $attrfunc = '') {
117 return '$("'.addslashes($domElement).'").jstree({
118 "core" : {"strings":{"loading":"Chargement ..."}},
119 "plugins" : ["themes","json_data"],
120 "themes" : { "url" : $.plURL("css/jstree.css") },
121 "json_data" : { "ajax" : {
122 "url" : $.plURL("'.addslashes($platalpage).'"),
123 "data" : function(nod) {
124 var jtid = 0;
125 if (nod != -1) {
126 jtid = nod.attr("id").replace(/^.*_([0-9]+)$/, "$1");
127 }
128 return {
129 "jtid" : jtid,
130 "treeid" : "'.addslashes($treeid).'",
131 "attrfunc" : "'.addslashes($attrfunc).'"
132 }
133 }
134 }} });';
135 }
136
137 /**
138 * Extract search token from term
139 * @param $term a utf-8 string that can contain any char
140 * @return an array of elementary tokens
141 */
142 static public function tokenize($term)
143 {
144 $term = mb_strtoupper(replace_accent($term));
145 $term = str_replace(array('/', ',', '(', ')', '"', '&', '»', '«'), ' ', $term);
146 $tokens = explode(' ', $term);
147 static $not_tokens = array('ET','AND','DE','DES','DU','D\'','OU','L\'','LA','LE','LES','PAR','AU','AUX','EN','SUR','UN','UNE','IN');
148 foreach ($tokens as &$t) {
149 $t = preg_replace(array('/^-+/','/-+$/'), '', $t);
150 if (substr($t, 1, 1) == '\'' && in_array(substr($t, 0, 2), $not_tokens)) {
151 $t = substr($t, 2);
152 }
153 if (strlen($t) == 1 || in_array($t, $not_tokens)) {
154 $t = false;
155 continue;
156 }
157 }
158 return array_filter($tokens);
159 }
160
161 /**
162 * Create the INNER JOIN query to restrict search to some job terms
163 * @param $tokens an array of the job terms to look for (LIKE comp)
164 * @param $table_alias the alias or name of the table with a jtid field to restrict
165 * @param $table_field the name of the field to restrict in table_alias, usually jtid
166 * @return a partial SQL query
167 */
168 static public function token_join_query(array $tokens, $table_alias, $table_field = 'jtid') {
169 $joins = '';
170 $i = 0;
171 foreach ($tokens as $t) {
172 ++$i;
173 $joins .= ' INNER JOIN profile_job_term_search AS s'.$i.' ON(s'.$i.'.jtid = '.$table_alias.'.'.$table_field.' AND s'.$i.'.search LIKE '.XDB::escape($t).')';
174 }
175 return $joins;
176 }
177 }
178
179 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker fenc=utf-8:
180 ?>