1<?php
2/***********************************************************
3 Copyright (C) 2008-2011 Hewlett-Packard Development Company, L.P.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 version 2 as published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17***********************************************************/
18
19/**
20 * \file bsam-license.php
21 * \brief functions for bsam UI
22 */
23
24/************************************************************
25 Developer notes:
26
27The confidence is a number used to identify how good the template is.
28Values are:
29NULL (not present) = use the template's name.
300 = high confidence. Use the template's name.  (Ignore canonical.)
311 = medium confidence. Most of the template matched.  Call it 'style'.
322 = low confidence. Part of the template matched.  Call it 'partial'.
333 = no confidence. The canonical identifier must be present and
34will be used.
35
36The canonical is the canonical name (licterm_pk from licterm).
37When the confidence is 3, the canonical name will be used.
38************************************************************/
39
40/**
41 * \brief Given a name, remove all of the extraneous text.
42 */
43function LicenseNormalizeName($LicName,$Confidence,$CanonicalName)
44{
45  /* Find the right name to use */
46  $Name = $CanonicalName;
47  if ($Confidence < 3)
48  {
49    if (!empty($CanonicalName)) {
50      $Name = $CanonicalName;
51    }
52    else
53    {
54      $Name = $LicName;
55      $Name = preg_replace("@.*/@","",$Name);
56      $Name = preg_replace("/ part.*/","",$Name);
57      $Name = preg_replace("/ short.*/","",$Name);
58      $Name = preg_replace("/ variant.*/","",$Name);
59      $Name = preg_replace("/ reference.*/","",$Name);
60      $Name = preg_replace("/ \(.*/","",$Name);
61    }
62    if ($Confidence == 1) {
63      $Name = "'$Name'-style";
64    }
65    else if ($Confidence == 2) {
66      $Name = "'$Name'-partial";
67    }
68  }
69  return($Name);
70} // LicenseNormalizeName()
71
72/**
73 * \brief Given a meta id (agent_lic_meta_pk), return
74 * the license name (mapped to canonical name).
75 */
76$LicenceGetName_Prepared=0;
77function LicenseGetName(&$MetaId, $IncludePhrase=0)
78{
79  global $PG_CONN;
80  global $LicenceGetName_Prepared;
81  if (!$LicenceGetName_Prepared)
82  {
83    $sql1 = 'SELECT licterm.licterm_name,lic_name,phrase_text,lic_id
84        FROM agent_lic_raw
85        INNER JOIN agent_lic_meta ON agent_lic_meta_pk = $1
86        AND lic_fk = lic_pk
87        INNER JOIN licterm_maplic ON licterm_maplic.lic_fk = lic_id
88        INNER JOIN licterm ON licterm_fk = licterm_pk
89        ;';
90    pg_prepare($PG_CONN, "LicenseGetName_Raw", $sql);
91
92    $sql2 = 'SELECT licterm_name_confidence,licterm_name
93        FROM licterm
94        INNER JOIN licterm_name ON agent_lic_meta_fk = $1
95        AND licterm_fk = licterm_pk
96        UNION
97        SELECT licterm_name_confidence,' . "''" . '
98        FROM licterm_name
99        WHERE agent_lic_meta_fk = $1 AND licterm_fk IS NULL
100        ;';
101    pg_prepare($PG_CONN, "LicenseGetName_CanonicalName", $sql2);
102    $LicenceGetName_Prepared=1;
103  }
104
105  $result =  pg_execute($PG_CONN, "LicenseGetName_CanonicalName",array($MetaId));
106  $CanonicalList = pg_fetch_all($result);
107  pg_free_result($result);
108  $result =  pg_execute($PG_CONN, "LicenseGetName_Raw",array($MetaId));
109  $RawList= pg_fetch_all($result);
110  pg_free_result($result);
111
112  $LastConfidence = $CanonicalList[0]['licterm_name_confidence'];
113  $Phrase = $RawList[0]['phrase_text'];
114  $FullName = '';
115  foreach($CanonicalList as $C)
116  {
117    if (empty($C)) {
118      continue;
119    }
120    /* Get the components */
121    $Confidence = $C['licterm_name_confidence'];
122    $LicTerm = $C['licterm_name'];
123
124    /* Normalize the name */
125    $Name = $RawList[0]['licterm_name'];
126
127    if (!empty($Phrase) && ($Confidence < 3))
128    {
129      $Name = "Phrase";
130      if ($IncludePhrase) {
131        $Name .= ": $Phrase";
132      }
133    }
134
135    /* Store it */
136    if (!empty($FullName))
137    {
138      if (empty($LastConfidence) || ($LastConfidence < 3) && ($Confidence >= 3) ) {
139        $FullName .= " + ";
140      }
141      else { $FullName .= ", ";
142      }
143    }
144    $FullName .= $Name;
145    $LastConfidence = $Confidence;
146  }
147
148  if (empty($FullName))
149  {
150    $Name = $RawList[0]['licterm_name'];
151    if (!empty($Phrase))
152    {
153      $Name = "Phrase";
154      if ($IncludePhrase) {
155        $Name .= ": $Phrase";
156      }
157    }
158    $FullName .= $Name;
159  }
160
161  return($FullName);
162} // LicenseGetName()
163
164/**
165 * \brief Return licenses for a pfile.
166 * May return empty array if there is no license.
167 */
168$LicenseGet_Prepared=0;
169function LicenseGet(&$PfilePk, &$Lics, $GetField=0)
170{
171  global $LicenseGet_Prepared;
172  global $PG_CONN;
173
174  if (!$LicenseGet_Prepared)
175  {
176    pg_prepare($PG_CONN, "LicenseGet_Raw1",'SELECT licterm.licterm_name,lic_id,phrase_text,agent_lic_meta_pk
177        FROM agent_lic_meta
178        INNER JOIN agent_lic_raw ON lic_fk = lic_pk AND pfile_fk = $1
179        INNER JOIN licterm_maplic ON licterm_maplic.lic_fk = lic_id
180        INNER JOIN licterm ON licterm_fk = licterm_pk
181        ;');
182    pg_prepare($PG_CONN, "LicenseGet_Raw2",'SELECT lic_name as licterm_name,lic_id,phrase_text,agent_lic_meta_pk
183        FROM agent_lic_meta
184        INNER JOIN agent_lic_raw ON lic_fk = lic_pk AND pfile_fk = $1
185        ;');
186    pg_prepare($PG_CONN, "LicenseGet_Canonical",'SELECT licterm.licterm_name,licterm_name_confidence,lic_name,phrase_text,lic_id,agent_lic_meta_pk
187        FROM agent_lic_meta
188        INNER JOIN agent_lic_raw ON lic_fk = lic_pk AND pfile_fk = $1
189        INNER JOIN licterm_name ON agent_lic_meta_fk = agent_lic_meta_pk
190        INNER JOIN licterm ON licterm_fk = licterm_pk
191        UNION
192        SELECT '."''".',licterm_name_confidence,lic_name,phrase_text,lic_id,agent_lic_meta_pk
193        FROM agent_lic_meta
194        INNER JOIN agent_lic_raw ON lic_fk = lic_pk AND pfile_fk = $1
195        INNER JOIN licterm_name ON agent_lic_meta_fk = agent_lic_meta_pk
196        AND licterm_fk IS NULL
197        ;');
198    $LicenseGet_Prepared=1;
199  }
200  if (empty($Lics[' Total '])) {
201    $Lics[' Total ']=0;
202  }
203
204  /* Prepare map */
205  $sql = "SELECT * FROM licterm_maplic INNER JOIN licterm ON licterm_fk = licterm_pk;";
206  $result = pg_query($PG_CONN, $sql);
207  DBCheckResult($result, $sql, __FILE__, __LINE__);
208
209  $MapLic = array();
210  while ($row = pg_fetch_assoc($result))
211  {
212    $MapLic[$row['lic_fk']] = $row['licterm_name'];
213  }
214  pg_free_result($result);
215
216  $result = pg_execute($PG_CONN, "LicenseGet_Canonical",array($PfilePk));
217  $CanonicalList = pg_fetch_all($result);
218  pg_free_result($result);
219  $result = pg_execute($PG_CONN, "LicenseGet_Raw1",array($PfilePk));
220  $RawList = pg_fetch_all($result);
221  pg_free_result($result);
222  if (empty($RawList)) {
223    $result = pg_execute($PG_CONN, "LicenseGet_Raw2",array($PfilePk));
224    $RawList = pg_fetch_all($result);
225    pg_free_result($result);
226  }
227  $Results=array();
228  $PfileList=array(); /* used to omit duplicates */
229  foreach($CanonicalList as $R)
230  {
231    $PfileList[$R['agent_lic_meta_pk']] = 1;
232    $Results[] = $R;
233  }
234  foreach($RawList as $R)
235  {
236    $R['licterm_name'] = LicenseNormalizeName($R['licterm_name'],0,"");
237    if (empty($PfileList[$R['agent_lic_meta_pk']]))
238    {
239      $PfileList[$R['agent_lic_meta_pk']] = 1;
240      $Results[] = $R;
241    }
242  }
243
244  if (!empty($Results) && (count($Results) > 0))
245  {
246    /* Got canonical name */
247    foreach($Results as $Name)
248    {
249      $LicName="";
250      if ($Name['licterm_name_confidence'] == 3) {
251        $LicName = $Name['licterm_name'];
252      }
253      if (empty($LicName)) {
254        $LicName = LicenseNormalizeName($Name['lic_name'],$Name['licterm_name_confidence'],$MapLic[$Name['lic_id']]);
255      }
256      if (empty($LicName)) {
257        $LicName = LicenseNormalizeName($Name['lic_name'],$Name['licterm_name_confidence'],$Name['licterm_name']);
258      }
259
260      if (!empty($LicName))
261      {
262        if (!empty($GetField)) {
263          $Lics[]=$Name;
264        }
265        else
266        {
267          if (empty($Lics[$LicName])) {
268            $Lics[$LicName]=1;
269          }
270          else { $Lics[$LicName]++;
271          }
272          $Lics[' Total ']++;
273        }
274      }
275    }
276  }
277  return;
278} // LicenseGet()
279
280/**
281 * \brief  Return license count for a uploadtree_pk.
282 * If uploadtree_pk is a file, the # of licenses in that file
283 * is returned.
284 * If uploadtree_pk is a container, the # of licenses contained
285 * in that container (and children) is returned.
286 */
287function LicenseCount($UploadtreePk)
288{
289  global $Plugins;
290  global $PG_CONN;
291  global $LicenseCount_Prepared;
292
293  if (empty($UploadtreePk)) {
294    return 0;
295  }
296
297  $sql = "SELECT lft,rgt,upload_fk FROM uploadtree WHERE uploadtree_pk = $UploadtreePk;";
298  $result = pg_query($PG_CONN, $sql);
299  DBCheckResult($result, $sql, __FILE__, __LINE__);
300  $row = pg_fetch_assoc($result);
301  pg_free_result($result);
302
303  $Lft = $row['lft'];
304  $Rgt = $row['rgt'];
305  $UploadFk = $row['upload_fk'];
306
307  if (!$LicenseCount_Prepared)
308  {
309    pg_prepare($PG_CONN, "LicenseCount",'SELECT sum(pfile_liccount) AS count
310    FROM uploadtree AS ut1
311    INNER JOIN pfile ON ut1.pfile_fk = pfile_pk
312    AND ut1.upload_fk = $1
313    AND ut1.lft BETWEEN $2 AND $3
314    WHERE pfile_liccount IS NOT NULL
315    ;');
316    $LicenseCount_Prepared=1;
317  }
318  $result = pg_execute($PG_CONN, "LicenseCount",array($UploadFk,$Lft,$Rgt));
319  $row = pg_fetch_assoc($result);
320  pg_free_result($result);
321  return($row['count']);
322} // LicenseCount()
323
324/**
325 * \brief Given a license name and uploadtree_pk,
326 * \return each file containing the license.
327 */
328function LicenseSearch(&$UploadtreePk, $WantLic=NULL, $Offset=-1, $Max=0)
329{
330  global $PG_CONN;
331  if (empty($UploadtreePk)) {
332    return NULL;
333  }
334
335  /* Get the range */
336  $sql = "SELECT lft,rgt,upload_fk FROM uploadtree WHERE uploadtree_pk = $UploadtreePk;";
337  $result = pg_query($PG_CONN, $sql);
338  DBCheckResult($result, $sql, __FILE__, __LINE__);
339  $row = pg_fetch_assoc($result);
340  pg_free_result($result);
341
342  $Lft = $row['lft'];
343  $Rgt = $row['rgt'];
344  $UploadFk = $row['upload_fk'];
345
346  /* Determine the license name */
347  $LicName = preg_replace("/'(.*)'-style/",'${1}',$WantLic);
348  $LicName = str_replace("'","''",$LicName);
349  if ($LicName == $WantLic)
350  {
351    /* Absolute name match */
352    $SQL = "SELECT
353      CASE
354      WHEN lic_tokens IS NULL THEN licterm_name
355      WHEN tok_match = lic_tokens THEN licterm_name
356      ELSE '''' || licterm_name || '''-style'
357      END AS licterm_name,
358          agent_lic_meta.*,
359          lic_tokens,
360          UT1.pfile_fk AS pfile,
361          UT1.*
362            FROM uploadtree AS UT1,
363          licterm_name, licterm, agent_lic_meta, agent_lic_raw
364            WHERE
365            UT1.lft BETWEEN $Lft AND $Rgt
366            AND licterm.licterm_name = '$LicName'
367            AND UT1.upload_fk=$UploadFk
368            AND licterm_name.pfile_fk=UT1.pfile_fk
369            AND licterm_pk=licterm_name.licterm_fk
370            AND agent_lic_meta_pk = licterm_name.agent_lic_meta_fk
371            AND agent_lic_meta.lic_fk = agent_lic_raw.lic_pk
372            AND (lic_tokens IS NULL OR
373                tok_match = lic_tokens)
374            ORDER BY pfile,agent_lic_meta_pk,ufile_name";
375    if ($Offset > 0) {
376      $SQL .= " OFFSET $Offset";
377    }
378    if ($Max > 0) {
379      $SQL .= " LIMIT $Max";
380    }
381    $SQL .= ";";
382  }
383  else
384  {
385    /* Match for style */
386    $SQL = "SELECT
387      UT1.*,phrase_text
388      FROM uploadtree AS UT1,
389           licterm_name, licterm, agent_lic_meta, agent_lic_raw
390             WHERE
391             UT1.lft BETWEEN $Lft and $Rgt
392             AND UT1.upload_fk=$UploadFk
393             AND licterm.licterm_name = '$LicName'
394             AND licterm_name.pfile_fk=UT1.pfile_fk
395             AND licterm_pk=licterm_name.licterm_fk
396             AND agent_lic_meta_pk = licterm_name.agent_lic_meta_fk
397             AND agent_lic_meta.lic_fk = agent_lic_raw.lic_pk
398             AND lic_tokens IS NOT NULL
399             AND tok_match != lic_tokens
400             AND CAST(tok_match AS numeric)/CAST(lic_tokens AS numeric) > 0.5
401             ORDER BY pfile_fk,ufile_name";
402    if ($Offset > 0) {
403      $SQL .= " OFFSET $Offset";
404    }
405    if ($Max > 0) {
406      $SQL .= " LIMIT $Max";
407    }
408    $SQL .= ";";
409  }
410  $result = pg_query($PG_CONN, $SQL);
411  DBCheckResult($result, $SQL, __FILE__, __LINE__);
412  $Results = pg_fetch_all($result);
413  pg_free_result($result);
414
415  return($Results);
416} // LicenseSearch()
417
418/**
419 * \brief Return licenses for a uploadtree_pk.
420 * Array returned looks like Array[license_name] = count.
421 * An array is always returned unless the db is not open
422 * or no uploadtreepk is passed in.
423 * $Max: $Max # of returned records
424 * $Offset: offset into $Results of first returned rec
425 *
426 * \returns NULL if not processed.
427 */
428function LicenseGetAll(&$UploadtreePk, &$Lics, $GetField=0, $WantLic=NULL)
429{
430  global $PG_CONN;
431
432  if (empty($UploadtreePk)) {
433    return NULL;
434  }
435
436  /* Number of licenses */
437  if (empty($Lics[' Total ']) && empty($GetField)) {
438    $Lics[' Total ']=0;
439  }
440
441  if ($Offset > 0)
442  $OffsetPhrase = " OFFSET $Offset";
443  else
444  $OffsetPhrase = "";
445
446  if ($Max > 0)
447  $LimitPhrase = " LIMIT $Max";
448  else
449  $LimitPhrase = "";
450
451  /* Get the range */
452  $sql = "SELECT lft,rgt,upload_fk FROM uploadtree WHERE uploadtree_pk = $UploadtreePk;";
453  $result = pg_query($PG_CONN, $sql);
454  DBCheckResult($result, $sql, __FILE__, __LINE__);
455  $row = pg_fetch_assoc($result);
456  pg_free_result($result);
457
458  $Lft = $row['lft'];
459  $Rgt = $row['rgt'];
460  $UploadFk = $row['upload_fk'];
461
462  /*  Get every license for every file in this subtree */
463  /** If % match > 50%, then count it.  (Skip things like 5% match.)
464   Anything less than 100% is '-style' **/
465  $SQL = "SELECT
466    CASE
467    WHEN lic_tokens IS NULL THEN licterm_name
468    WHEN tok_match = lic_tokens THEN licterm_name
469    ELSE '''' || licterm_name || '''-style'
470    END AS licterm_name
471    FROM uploadtree AS UT1,
472         licterm_name, licterm, agent_lic_meta, agent_lic_raw
473           WHERE
474           UT1.lft BETWEEN $Lft and $Rgt
475           AND UT1.upload_fk=$UploadFk
476           AND licterm_name.pfile_fk=UT1.pfile_fk
477           AND licterm_pk=licterm_name.licterm_fk
478           AND agent_lic_meta_pk = licterm_name.agent_lic_meta_fk
479           AND agent_lic_meta.lic_fk = agent_lic_raw.lic_pk
480           AND (lic_tokens IS NULL OR
481               CAST(tok_match AS numeric)/CAST(lic_tokens AS numeric) >= 0.5)
482           ORDER BY licterm_name
483           ;";
484
485  $result = pg_query($PG_CONN, $SQL);
486  DBCheckResult($result, $SQL, __FILE__, __LINE__);
487  $Lics[' Total '] = 0;
488  $LastName='';
489  while ($Name = pg_fetch_assoc($result))
490  {
491    if (empty($Name)) {
492      continue;
493    }
494    $Lics[' Total ']++;
495    $Name = $Name['licterm_name'];
496    if ($Name == $LastName) {
497      $Lics[$Name]++;
498    }
499    else { $Lics[$Name]=1; $LastName = $Name;
500    }
501  }
502  pg_free_result($result);
503
504  return;
505} // LicenseGetAll()
506
507/**
508 * \brief Return licenses for a uploadtree_pk.
509 * This is only for search-file-by-licgroup.php
510 * License Groups only use the the license stored in agent_lic_meta
511 * Can return empty array if there is no license.
512 * $Max: $Max # of returned records
513 * $Offset: offset into $Results of first returned rec
514 * \return NULL if not processed.
515 */
516function LicenseGetAllFiles(&$UploadtreePk, &$Lics, &$WantLic, $Max, $Offset)
517{
518  global $Plugins;
519  global $PG_CONN;
520
521  if (empty($UploadtreePk)) {
522    return NULL;
523  }
524
525  /* Get the range */
526  $sql = "SELECT lft,rgt,upload_fk FROM uploadtree WHERE uploadtree_pk = $UploadtreePk;";
527  $result = pg_query($PG_CONN, $sql);
528  DBCheckResult($result, $sql, __FILE__, __LINE__);
529  $row = pg_fetch_assoc($result);
530  pg_free_result($result);
531  $Lft = $row['lft'];
532  $Rgt = $row['rgt'];
533  $UploadFk = $row['upload_fk'];
534
535  /*  Get every license for every file in this subtree */
536  /* SQL to get all files with a specific license */
537  $sql = "select UT1.*,lic_fk,lic_id,tok_pfile,tok_license,tok_match,phrase_text
538      FROM uploadtree as UT1
539      INNER JOIN agent_lic_meta
540      ON UT1.upload_fk=$UploadFk
541      AND UT1.lft BETWEEN $Lft and $Rgt
542      AND agent_lic_meta.pfile_fk = UT1.pfile_fk
543      INNER JOIN agent_lic_raw ON agent_lic_meta.lic_fk=agent_lic_raw.lic_pk
544      AND ( $WantLic )
545      ORDER BY UT1.ufile_name;";
546  $result = pg_query($PG_CONN, $sql);
547  DBCheckResult($result, $sql, __FILE__, __LINE__);
548  $Count = pg_num_rows($result);
549
550  if ($Max == -1) $Max = $Count;
551
552  /* Got canonical name */
553  $Found = 0;
554  while(($Found < $Max+$Offset) && ($row = pg_fetch_assoc($result)))
555  {
556    if ($Found >= $Offset)
557    {
558      $Lics[] = $row;
559    }
560    $Found++;
561  }
562  pg_free_result($result);
563
564  return;
565} // LicenseGetAllFiles()
566
567?>
568