src/NCBS/WebsiteBundle/Controller/NCBSWController.php line 7043

Open in your IDE?
  1. <?php
  2. namespace NCBS\WebsiteBundle\Controller;
  3. //s33: can remove now?
  4. use Skymark\UtilitiesBundle\Controller\DefaultController as BaseController;
  5. use Symfony\Component\DependencyInjection\ContainerInterface;
  6. use Symfony\Component\DependencyInjection\ContainerAwareInterface;
  7. use Symfony\Component\HttpFoundation\Response;
  8. //s33: i think we can use just 'Controller'
  9. use Symfony\Bundle\FrameworkBundle\Controller\Controller as SymCon;
  10. //class NCBSWController extends BaseController
  11. class NCBSWController extends SymCon
  12. {
  13.     private $language null;
  14.     protected $prefix "NCBSW";
  15.     protected $TRANSLATION_TYPE_ID_TEXT 1;
  16.     protected $TRANSLATION_TYPE_ID_FILE 2;
  17.     protected $TRANSLATION_TYPE_ID_LINK 3;
  18.     
  19.     protected $SC_SIMPLE_ENCRYPT_SEED 38;
  20.     
  21.     protected $STORY_LEVEL_ID_BIBLE 1;
  22.     protected $STORY_LEVEL_ID_VERSE 2;
  23.     protected $STORY_LEVEL_ID_CHAPTER 3;   
  24.     
  25.     protected $MEDIA_TYPE_ID_IMAGE 1;
  26.     protected $MEDIA_TYPE_ID_AUDIO 2
  27.     
  28.     protected $CATEGORY_ID_CONCEPT 12;
  29.     protected $CATEGORY_ID_SPIRITUAL_TOPIC 13
  30.     protected $CATEGORY_ID_BIBLE_STUDY 14
  31.     protected $CATEGORY_ID_SERMON 42
  32.     protected $CATEGORY_ID_DOCUMENTS 45
  33.     protected $CATEGORY_ID_BIBLE_STORY 46
  34.     protected $CATEGORY_ID_QA 47
  35.     protected $CATEGORY_ID_PROJECT 52;
  36.         
  37.     protected $MULTI_URL_INDICATOR_BIBLE 'bible';  
  38.     protected $MULTI_URL_INDICATOR_BIBLE_STORYTEXT 'biblestory';
  39.     protected $MULTI_URL_INDICATOR_SWEDENBORG_WORK 'swedenborg';
  40.     protected $MULTI_URL_INDICATOR_EXPLANATION 'explanation';
  41.     
  42.     protected $DEFAULT_BIBLE_VERSION 'king-james-version';
  43.     protected $DEFAULT_BIBLE_TRANSLATION_ID 38// king-james-version
  44.         
  45.     protected $LANGUAGE_ID_CHINESE 79;    
  46.     protected $LANGUAGE_ID_JAPANESE 205
  47.     protected $LANGUAGE_ID_KOREAN 231
  48.     protected $LANGUAGE_ID_ENGLISH 123;
  49.     protected $LANGUAGE_ID_LATIN 246;
  50.     protected $LANGUAGE_ID_THAI 426;
  51.     protected $LANGUAGE_ID_BURMESE 66;
  52.     protected $LANGUAGE_ID_MALAYALAM 268;
  53.     protected $LANGUAGE_ID_GEORGIAN 149;
  54.     protected $LANGUAGE_ID_AMHARIC 17;
  55.     protected $LANGUAGE_ID_TAGALOG 425;
  56.     protected $LANGUAGE_ID_ZULU 482;
  57.     
  58.     protected $DEFAULT_PATH_TITLE_COLOR '#6b9054;';
  59.     
  60.     protected $READING_PLAN_STATUS_ID_COMPLETED 4;
  61.     
  62.     protected $RELATIONSHIP_TYPE_ID_PARALLEL 1;
  63.     
  64.     protected $USER_LEVEL_ID_EXPLANATION_AUTHOR 2;
  65.     
  66.     protected $TESTAMENT_OLDTESTAMENT 1;
  67.     protected $TESTAMENT_NEWTESTAMENT 2;
  68.     protected $TESTAMENT_APOCRYPHA 3;
  69.     
  70.     protected $TRANSLATION_METHOD_ID_NA 1// original
  71.     protected $TRANSLATION_METHOD_ID_MACHINE 2;
  72.     protected $TRANSLATION_METHOD_ID_HUMAN 3;
  73.     protected $TRANSLATION_METHOD_ID_MACHINE_HUMAN 4;
  74.     
  75.     protected $USER_LEVEL_ID_ADMIN = -1;
  76.     protected $USER_LEVEL_ID_APPLICATION_MANAGER 6;
  77.     protected $USER_LEVEL_ID_LNC_ADMIN 12;
  78.     protected $USER_LEVEL_ID_LNC_MEMBER_WEB_USER 13;
  79.     
  80.     protected $OTLE_SHOW_TYPE_ID_MUSIC 18;
  81.     
  82.     protected $PRIMARY_FORMAT_ID_TEXT 1;
  83.     protected $PRIMARY_FORMAT_ID_AUDIO 2;
  84.     protected $PRIMARY_FORMAT_ID_VIDEO 3;
  85.     
  86.     protected $BRAND_ID_OFF_THE_LEFT_EYE 3;
  87.     
  88.     protected $LOCATIONTYPE_ID_VIRTUAL 1;
  89.     protected $LOCATIONTYPE_ID_IN_PERSON 2;
  90.     
  91.     protected $LNCSERMON_TYPE_ID_ADMIN 1;
  92.     protected $LNCSERMON_TYPE_ID_PUBLIC 2;
  93.     protected $LNCSERMON_TYPE_ID_LNC_MEMBER 3;
  94.     
  95.     protected $PAGE_MESSAGE_ID_EMAIL_BY_DATE 1;
  96.     
  97.     protected $READINGPLAN_STEP_TYPE_ID_BIBLE 1;
  98.     protected $READINGPLAN_STEP_TYPE_ID_SWEDENBORG_WORK 2;
  99.     protected $READINGPLAN_STEP_TYPE_ID_EXPLANATION 3;
  100.     protected $READINGPLAN_STEP_TYPE_ID_ADHOC 4;
  101.     
  102.     protected $BRANCH_ID_LNC 6;
  103.     
  104.     protected $NC_ITEM_TYPE_ID_PLAIN_TEXT 1;
  105.     protected $NC_ITEM_TYPE_ID_HYPERLINK 2;
  106.     protected $NC_ITEM_TYPE_ID_FOOTNOTE 3;
  107.     protected $NC_ITEM_TYPE_ID_TRANSLATOR_FOOTNOTE_TEXT 4;
  108.     protected $NC_ITEM_TYPE_ID_SWEDENBORG_FOOTNOTE_TEXT 5;
  109.     protected $NC_ITEM_TYPE_ID_NCBS_FOOTNOTE_TEXT 6;
  110.     
  111.     protected $PERSON_ROLE_ID_AUTHOR 1;
  112.     protected $PERSON_ROLE_ID_TRANSLATOR 2;
  113.     
  114.     protected $NC_PARAMETER_ID 1;
  115.     
  116.     protected $LINK_TYPE_ID_BIBLE 1;
  117.     protected $LINK_TYPE_ID_SWEDENBORG 2;
  118.     protected $LINK_TYPE_ID_OTHER 3;
  119.     
  120.     public function setLanguage($languageUrl)
  121.     {
  122.         $language $this->getRepository('Language')->getOneByUrlCached($languageUrl);
  123.         if(empty($language)) {
  124.             throw $this->createNotFoundException("We don't seem to have that language available.");
  125.         }
  126.         $this->language $language;
  127.     }
  128.     public function getLanguage()
  129.     {
  130.         return $this->language;
  131.     }
  132.     // previously in utils ?  or orm ?
  133.     function getManager() {
  134.         return $this->getDoctrine()->getManager();
  135.     }
  136.     public function getNCBSWRepository($entityName)
  137.     {
  138.         // error_log("1545 NC now .. 2251 FIND A REPO: $entityName");
  139.         // return parent::getRepository('NCBSWBundle:' . $entityName);
  140.         return $this->getManager()->getRepository('NCBSWBundle:' $entityName);
  141.     }
  142.     function bibleData($x) {
  143.         // error_log("1551 NC: bibleData called: $x");
  144.         $em $this->getDoctrine()->getManager();
  145.         // $em = $this->getContainer()->get('doctrine.orm.entity_manager');
  146.         $bx $em->getRepository('NCBSWBundle:Bible\\' $x);
  147.         return $bx;
  148.     }
  149.     public function canonicalData($canonicalEntityName)
  150.     {
  151.         return $this->getNCBSWRepository('Bible\Canonical\\' $canonicalEntityName);
  152.     }
  153.     public function expositionData($expositionEntityName)
  154.     {
  155.         return $this->getNCBSWRepository('Exposition\\' $expositionEntityName);
  156.     }
  157.     // moved from Skymark\Utils
  158.     public function getRepository($entityName)
  159.     {
  160.         // error_log("1611 NC_Con - new getRepo($entityName) -- still called??");
  161.         // $em = $this->getDoctrine()->getManager();
  162.         $em $this->getManager();
  163.         // $em = $this->getContainer()->get('doctrine.orm.entity_manager');
  164.         $r $em->getRepository('NCBSWBundle:' $entityName);
  165.         return $r;
  166.     }
  167.      
  168.     public function renderView($view, array $parameters = array(), Response $response null)
  169.     {
  170.         // $path = $this->prefix . ':' . $view;
  171.         $path $this->prefix '/' $view;
  172.         
  173.         if($response != null)
  174.         {      
  175.             $response->setETag(md5($response->getContent()));
  176.             $response->setPublic(); // make sure the response is public/cacheable
  177.            // $response->isNotModified($this->getRequest());
  178.         }
  179.         //s33: cleanup -- except for templateName probably not needed
  180.         // error_log("0111 renderView 1 - " . $path);
  181.     $gtp $this->getGeneralTemplateParameters();
  182.     // error_log("0111 renderView 2 gtp: " . json_encode($gtp)); // , 0, 2));
  183.     // error_log("0111 renderView 2 p: " . json_encode($parameters)); // , 0, 2));
  184.         #$r = $this->render("NCBSWBundle:$path.html.twig", array_merge($gtp, $parameters), $response);
  185.     // for 3.3:
  186.     $templateName "@NCBSW/$path.html.twig";
  187.     // error_log("2134 template name: $templateName");
  188.     $r $this->render($templateNamearray_merge($gtp$parameters), $response);
  189.     // error_log("0111 renderView 3 ");
  190.         return $r;
  191.     }
  192.     protected function getGeneralTemplateParameters()
  193.     {
  194.         $generalParams = array();
  195.         $aLocale $this->container->getParameter('jms_i18n_routing.locales');
  196.         $aLang $this->getLanguageList($aLocale);
  197.     /*    foreach($this->container->getParameter('jms_i18n_routing.locales') as $localeCode) {
  198.             $generalParams['available_locales'][$localeCode] = $this->getRepository('Language')->findOneByShortCode($localeCode);
  199.         } */
  200.         
  201.         foreach($aLocale as $localeCode) {
  202.             $generalParams['available_locales'][$localeCode] = $aLang[$localeCode];
  203.         }
  204.         
  205.         return $generalParams;
  206.     }
  207.     
  208.     function getLanguageList($vLocal)
  209.     {        
  210.         $sLocals "'".implode("','"$vLocal)."'";
  211.         $sSql "select shortcode, (case when nativename is not null and nativename <> '' then nativename else name end) as name FROM language where shortcode in (" $sLocals ")";
  212.         $aTemp $this->getNativeQueryResults($sSql);
  213.         $aRet = array();
  214.         foreach($aTemp as $t)
  215.         {
  216.             $aRet[$t['shortcode']] = $t['name'];
  217.         }
  218.         
  219.         return $aRet;
  220.     }
  221.     
  222.     function getNativeQueryResults($sql)
  223.     {
  224.         $query $this->getManager()->getConnection()->prepare($sql);
  225.         $query->execute();
  226.         return $query->fetchAll();
  227.     }
  228.         
  229.     function getExplainedStoryList($locale$nStoryId=null)
  230.     {
  231.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  232.     
  233.         $sSql "select * from (select distinct on (id) * from (SELECT bs.id, case when bsl.name is null then bs.name else bsl.name end as name, url, explanationtitle, commentary_url, work_id, case when bs.language_id = " $nLanguageID " then 1 else case when bs.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end as lang_order, book_id, chapter_order, verse_order from vbiblestoryexplained bs left join (select * from biblestory_language where language_id = " $nLanguageID ") as bsl on bs.id = bsl.biblestory_id where ispublic";
  234.         if($nStoryId != null)
  235.             $sSql .= " and bs.id = " $nStoryId;
  236.         
  237.         $sSql .= " ) as t order by id, lang_order) as t2 order by book_id, chapter_order, verse_order";
  238. //    echo $sSql . "<br>";            
  239.         return $this->getNativeQueryResults($sSql);
  240.     }    
  241.     
  242.     function getWorkListForStory($locale$nStoryId=null)
  243.     {
  244.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  245.     
  246.         $sSql "select * from (select distinct on (work_id) * from (SELECT bs.id, case when bsl.name is null then bs.name else bsl.name end as name, url, explanationtitle, commentary_url, work_id, case when bs.language_id = " $nLanguageID " then 1 else case when bs.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end as lang_order, book_id, chapter_order, verse_order, bs.ordering as story_order from vbiblestoryexplained bs left join (select * from biblestory_language where language_id = " $nLanguageID ") as bsl on bs.id = bsl.biblestory_id where ispublic";
  247.         if($nStoryId != null)
  248.             $sSql .= " and bs.id = " $nStoryId;
  249.         
  250.         $sSql .= " ) as t order by work_id, lang_order) as t2 order by story_order, book_id, chapter_order, verse_order";
  251.  //   echo $sSql . "<br>";            
  252.         return $this->getNativeQueryResults($sSql);
  253.     }  
  254. /*        
  255.     // not used
  256.     function getUnexplainedStoryList($locale)
  257.     {
  258.         $sSql = "SELECT name, url from vbiblestory where";        
  259.         $sSql .= ' id not in (select id from vbiblestoryexplained)';            
  260.         $sSql .= " order by book_id, chapter_order, verse_order, name";    
  261.                 
  262.         return $this->getNativeQueryResults($sSql);
  263.     }
  264. */
  265.     
  266.     function getChapterExplanation($nChapterID$sBibleTranslationUrl$request$vFromSlider=false)
  267.     {
  268.         $nUILanguageID $this->getUILanguageID($request);
  269.         $nPreferredLanguageID $this->getUserPreferredLanguageID($request);
  270.         
  271.         $nSelectedExplTransID $request->query->get('et');
  272.         
  273.         $nBookLanguageID null;
  274.         $sEndStr "";
  275.         $sLangFilter "";
  276.         $sLangOrder "";
  277.         if(!empty($sBibleTranslationUrl))
  278.         {
  279.             $sSql1 "select language_id from bibletranslation where url = '" str_replace("'""''"$sBibleTranslationUrl) . "'";
  280.             //echo $sSql1;
  281.             $nBookLanguageID $this->getSingleData($sSql1);
  282.         }    
  283.         
  284.         if(!$vFromSlider && !$this->showBibleChapterSummary($nBookLanguageID))
  285.         {
  286.             return array();
  287.         }
  288.         
  289.         if(!empty($nBookLanguageID))
  290.         {    
  291.             if(!empty($nSelectedExplTransID))
  292.             {    
  293.                 $sLangOrder .= "case when t.id = " $nSelectedExplTransID " then 1 else ";
  294.                 $sEndStr .= " end ";
  295.             }    
  296.         
  297.             $sLangOrder .= "case when t.language_id = " $nBookLanguageID " then 2";
  298.             
  299.             $sLangFilter .= " and (t.language_id in (" $nBookLanguageID;
  300.             
  301.             if($nBookLanguageID != $nUILanguageID)
  302.             {
  303.                 $sLangOrder .= " else case when t.language_id = " $nUILanguageID " then 3";
  304.                 $sEndStr .= " end ";
  305.                 $sLangFilter .= "," $nUILanguageID;
  306.             }
  307.             
  308.             if(!empty($nPreferredLanguageID) && $nBookLanguageID != $nPreferredLanguageID && $nUILanguageID != $nPreferredLanguageID)
  309.             {
  310.                 $sLangOrder .= ' else case when t.language_id = ' $nPreferredLanguageID ' then 4';    
  311.                 $sEndStr .= " end ";
  312.                 $sLangFilter .= "," $nPreferredLanguageID;
  313.             }
  314.                                     
  315.             if($nBookLanguageID != $this->LANGUAGE_ID_ENGLISH && $nUILanguageID != $this->LANGUAGE_ID_ENGLISH && $nPreferredLanguageID != $this->LANGUAGE_ID_ENGLISH)
  316.             {
  317.                 $sLangOrder .= " else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 5";
  318.                 $sEndStr .= " end ";
  319.                 $sLangFilter .= "," $this->LANGUAGE_ID_ENGLISH;
  320.             }
  321.                         
  322.             $sLangOrder .= " else 6";
  323.         }
  324.         else
  325.         {
  326.             $sLangFilter .= " and (t.language_id in (";
  327.             
  328.             if(!empty($nSelectedExplTransID))
  329.             {    
  330.                 $sLangOrder .= "case when t.id = " $nSelectedExplTransID " then 1 else";
  331.                 $sEndStr .= " end ";
  332.             }
  333.             
  334.             $sLangOrder .= " case when t.language_id = " $nUILanguageID " then 2";
  335.             
  336.             $sLangFilter .= $nUILanguageID;
  337.             
  338.             if($nUILanguageID != $this->LANGUAGE_ID_ENGLISH)
  339.             {
  340.                 $sLangOrder .= " else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3";
  341.                 $sEndStr .= " end ";
  342.                 $sLangFilter .= "," $this->LANGUAGE_ID_ENGLISH;
  343.             }
  344.             else
  345.             {
  346.                 $sLangOrder .= " else 3";                
  347.             }
  348.         }        
  349.                 
  350.         $sLangOrder .= $sEndStr " end as lang_order";
  351.         $sLangFilter .= ")";
  352.         
  353.         if(!empty($nSelectedExplTransID))
  354.         {    
  355.             $sLangFilter .= " or t.id = " $nSelectedExplTransID;
  356.         }
  357.         
  358.         $sLangFilter .= ")";
  359.     
  360.         $sSql "SELECT bs.chapter_id, t.id as translation_id, t.url, t.is_modern, t.translatedtitle as explanationtitle, " $sLangOrder
  361.                 ." FROM expositionwork w, expositiontranslation t, expositiontranslationtext tt, story_work sw, biblestory bs"
  362.                 ." WHERE bs.chapter_id = " $nChapterID " and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and t.id = tt.translation_id and tt.text is not null and tt.text <> ''"
  363.                 $sLangFilter
  364.                 ." and w.ispublic AND t.ispublic order by lang_order, t.is_modern desc, t.islanguagedefault desc limit 1";
  365.       //  echo $sSql."<br>";            
  366.         return $this->getNativeQueryResults($sSql);
  367.     } 
  368.     
  369.     function getAuthorInfo($request$translationId)
  370.     {
  371.         $sAuthor "";
  372.         $nTransID "";
  373.         // check if it's machine translated
  374.         $sSql1 "select translationmethod_id from expositiontranslation where id = " $translationId;
  375.         $nTransMethodID $this->getSingleData($sSql1);
  376.         $bOriginal = ($nTransMethodID == $this->TRANSLATION_METHOD_ID_NA);
  377.         $bMachineTranslated = ($nTransMethodID == $this->TRANSLATION_METHOD_ID_MACHINE);
  378.         
  379.         // get the original translation with the same work ID as the translated one
  380.         $sSql2 "select t2.id from expositiontranslation t1, expositiontranslation t2 where t1.id = " $translationId " and t1.work_id = t2.work_id and t2.isoriginal order by case when t2.language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end";
  381.         $nTransID $this->getSingleData($sSql2);
  382.         if(!empty($nTransID))
  383.         {
  384.             $sSql "SELECT array_to_string(array_agg( (CASE WHEN p.name is not null then p.name else (case when p.title is null then '' else p.title || ' ' end) || (case when p.firstname is null then '' else p.firstname || ' ' end) || (case when p.middlename is null then '' else p.middlename || ' ' end) || (case when p.lastname is null then '' else p.lastname || ' ' end) || (case when p.suffix is null then '' else p.suffix || ' ' end) end) ), ', ') as authors "
  385.                     ." FROM translation_bibliographicdata tbg, bibliographicdata_person bp, person p"
  386.                     ." WHERE tbg.translation_id = " $nTransID " and tbg.bibliographicdata_id = bp.bibliographicdata_id and bp.person_id = p.id";
  387.             $sAuthor $this->getSingleData($sSql);  
  388.         }
  389.           
  390.         if(!$bOriginal)        
  391.         {            
  392.             // get the translated language
  393.             $sSql3 "select (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name from expositiontranslation t, language l where t.id = " $translationId " and l.id = t.language_id";
  394.             $sLang $this->getSingleData($sSql3);
  395.             
  396.             if(!empty($sLang))
  397.             {
  398.                 if($bMachineTranslated)
  399.                 {
  400.                     $sAuthor .= " (" $request->getSession()->get('ui_str')["generic.machinetranslated"] . " " $sLang ")";
  401.                 }    
  402.                 else
  403.                 {
  404.                     $sSql "SELECT array_to_string(array_agg( (CASE WHEN p.name is not null then p.name else (case when p.title is null then '' else p.title || ' ' end) || (case when p.firstname is null then '' else p.firstname || ' ' end) || (case when p.middlename is null then '' else p.middlename || ' ' end) || (case when p.lastname is null then '' else p.lastname || ' ' end) || (case when p.suffix is null then '' else p.suffix || ' ' end) end) ), ', ') as authors "
  405.                     ." FROM translation_bibliographicdata tbg, bibliographicdata_person bp, person p"
  406.                     ." WHERE tbg.translation_id = " $translationId " and tbg.bibliographicdata_id = bp.bibliographicdata_id and bp.person_id = p.id and bp.role_id = " $this->PERSON_ROLE_ID_TRANSLATOR;
  407.                     $sTranslator $this->getSingleData($sSql);
  408.                     if(empty($sTranslator))
  409.                     {
  410.                         $aReplace = array(
  411.                             '_9600_' => $sLang
  412.                         );
  413.                        $sAuthor .= " (" $this->ui_string_replace($request->getSession()->get('ui_str')["exposition.translation.translated.into"], $aReplace) . ")";
  414.                     }
  415.                     else
  416.                     {
  417.                         $aReplace = array(
  418.                             '_9600_' => $sLang,
  419.                             '_9700_' => $sTranslator
  420.                         );
  421.                        $sAuthor .= " (" $this->ui_string_replace($request->getSession()->get('ui_str')["exposition.translation.translated.intoby"], $aReplace) . ")";
  422.                     }
  423.                 }    
  424.             }   
  425.         }    
  426.                 
  427.         return $sAuthor;        
  428.     } 
  429.      
  430.     function checkBibleTranslationMsg($translationUrl)
  431.     {
  432.         $msgData = array();
  433.         if($translationUrl == 'albanian') { 
  434.             $msgData['no_content_msg'] = "Unfortunately, there's currently no longer a Shqip (Albanian) Bible translation available to us. Wikipedia lists some translations here: <a href='https://en.wikipedia.org/wiki/Bible_translations_into_Albanian'>https://en.wikipedia.org/wiki/Bible_translations_into_Albanian</a>";            
  435.         }  
  436.         
  437.         if($translationUrl == 'romanian-cornilescu') {                       
  438.             $msgData['no_content_msg'] = "Unfortunately, there's currently no longer a Cornilescu (Romanian) Bible translation available to us. Wikipedia lists some translations here: <a href='https://en.wikipedia.org/wiki/Bible_translations_into_Cornilescu'>https://en.wikipedia.org/wiki/Bible_translations_into_Cornilescun</a>";
  439.             
  440.         } 
  441.         
  442.         return $msgData;
  443.     } 
  444.     
  445.     function getTextStyleOverride($languageId)
  446.     {
  447.         $sSql "SELECT text_style_override "
  448.                 ." FROM language"
  449.                 ." WHERE id = " $languageId;
  450.         $sRet '';
  451.         $aRet $this->getNativeQueryResults($sSql);
  452.         if(count($aRet) > 0
  453.             $sRet implode(''$aRet[0]);        
  454.                 
  455.         return $sRet;        
  456.     }
  457.     
  458.     function getTextStyleOverrideForBible($book_id)
  459.     {
  460.         $sSql "SELECT l.text_style_override "
  461.                 ." FROM language l, bibletranslation bt, biblebook b"
  462.                 ." WHERE b.id = " $book_id " and b.translation_id = bt.id and l.id = bt.language_id";
  463.         $sRet '';
  464.         $aRet $this->getNativeQueryResults($sSql);
  465.         if(count($aRet) > 0
  466.             $sRet implode(''$aRet[0]);        
  467.                 
  468.         return $sRet;        
  469.     }  
  470.     
  471.     function getNextPassageWithContent($passage,$translation)
  472.     {
  473.         $sSql "SELECT p.id, t.url as translation_url, d.url as division_url, (case when p.swedenborgsection is not null then p.swedenborgsection else cast(p.ordering as text) end) as passage_num, p.ordering as passage_order, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '_' || p.ordering end) as multi_spec "
  474.                 ." FROM expositionpassage p, expositiondivision d, expositiontranslationtext tt, expositiontextunit tu, expositiontranslation t, expositionwork w"
  475.                 ." WHERE d.work_id = " $passage->getDivision()->getWork()->getId() . " and p.division_id = d.id and p.ordering > " $passage->getOrdering() . " and tt.translation_id=" $translation->getId() . " and tt.placement_id = tu.id and tu.passage_id = p.id and t.id = tt.translation_id and d.work_id = w.id order by p.ordering limit 1";
  476.      //           echo $sSql."<br>";
  477.         $aRet = array();
  478.         $aTemp $this->getNativeQueryResults($sSql);
  479.         if(count($aTemp) > 0
  480.             $aRet $aTemp[0];        
  481.                 
  482.         return $aRet;         
  483.     }   
  484.     
  485.     function getPreviousPassageWithContent($passage,$translation)
  486.     {
  487.         $sSql "SELECT p.id, t.url as translation_url, d.url as division_url,  (case when p.swedenborgsection is not null then p.swedenborgsection else cast(p.ordering as text) end) as passage_num, p.ordering as passage_order, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '_' || p.ordering end) as multi_spec "
  488.                 ." FROM expositionpassage p, expositiondivision d, expositiontranslationtext tt, expositiontextunit tu, expositiontranslation t, expositionwork w"
  489.                 ." WHERE d.work_id = " $passage->getDivision()->getWork()->getId() . " and p.division_id = d.id and p.ordering < " $passage->getOrdering() . " and tt.translation_id=" $translation->getId() . " and tt.placement_id = tu.id and tu.passage_id = p.id and t.id = tt.translation_id and d.work_id = w.id order by p.ordering desc limit 1";
  490.      //          echo $sSql."<br>";
  491.         $aRet = array();
  492.         $aTemp $this->getNativeQueryResults($sSql);
  493.         if(count($aTemp) > 0
  494.             $aRet $aTemp[0];        
  495.                 
  496.         return $aRet;          
  497.     }   
  498.             
  499.     function getCategorizedSwedenborgWorks($request$language_id=123)
  500.     {        
  501.         return $this->getCategorizedSwedenborgWorksForTranslation($requestnull$language_id);
  502.     } 
  503.     
  504.     function getCategorizedSwedenborgWorksForTranslation($request$translation_id$language_id=123)
  505.     {        
  506.         $sPublished $request->getSession()->get('ui_str')["exposition.breadcrumbs.publishedworks"];
  507.         $sUnpublished $request->getSession()->get('ui_str')["exposition.breadcrumbs.unpublishedworks"];
  508.         $sScientific $request->getSession()->get('ui_str')["exposition.breadcrumbs.scientificworks"];
  509.         $sTransitional $request->getSession()->get('ui_str')["exposition.breadcrumbs.transitionalworks"];
  510.         
  511.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id, t.id as translation_id, t.url as translation_url, t.translatedtitle AS title, (case when w.swedenborgtype = 'published' then '" str_replace("'""''"$sPublished) . "' else case when w.swedenborgtype = 'unpublished' then '" str_replace("'""''"$sUnpublished) . "' else case when w.swedenborgtype = 'transitional' then '" str_replace("'""''"$sTransitional) . "' else case when w.swedenborgtype = 'scientific' then '" str_replace("'""''"$sScientific) . "' else 'Unknown' end end end end) as sw_type, case when t.language_id = ".$language_id ." then 1 else 2 end as lang_order, case when t.islanguagedefault then 1 else 2 end as default_order, w.swedenborgtype, wt.ordering as type_order"
  512.                 ." FROM expositionwork w, expositiontranslation t, expositionworktype wt"
  513.                 ." WHERE w.swedenborgtype IS NOT NULL and t.work_id=w.id and w.swedenborgtype = wt.name";
  514.        
  515.        if($language_id == $this->LANGUAGE_ID_ENGLISH)         
  516.                $sSql .= " and t.language_id = ".$language_id;
  517.        else
  518.                $sSql .= " and t.language_id in (" $this->LANGUAGE_ID_ENGLISH ", ".$language_id.")";
  519.                 
  520.        if($translation_id != null)
  521.                $sSql .= " and (t.id = " $translation_id " or w.id not in (select work_id from expositiontranslation where id = " $translation_id "))"
  522.                
  523.        $bShowScientific $this->showScientific($request);
  524.        if(!$bShowScientific)
  525.                $sSql .= " and w.swedenborgtype <> 'scientific'";        
  526.                 
  527.        $sSql .= " and w.ispublic AND t.ispublic and t.url is not null and t.url <> '' order by w.id, lang_order, default_order) as w2 order by w2.type_order, w2.lang_order, w2.title";
  528.  //    echo $sSql."<br>";       
  529.         return $this->getNativeQueryResults($sSql); 
  530.     } 
  531.     
  532.     function getWorkPassageRefs($passage_id,$translation_id$request$bCheck=false)
  533.     {        
  534.         $language_id $this->getLanguageIDByTranslation($translation_id);
  535.         $bLangStr = ($language_id != null && $language_id != $this->LANGUAGE_ID_ENGLISH);
  536.         
  537.         $sSql1 "select array_to_string(array_agg(DISTINCT d.ref_id),',') as ref from expositiontextunit t, expositiontranslationtext tt, expositiondisplayitem d where t.passage_id = " $passage_id " and tt.translation_id = " $translation_id
  538.                 ." and t.id = tt.placement_id and d.container_id = tt.id and d.type_id = " $this->NC_ITEM_TYPE_ID_HYPERLINK;
  539.                 
  540.         $aHyperLink $this->getNativeQueryResults($sSql1);    
  541.         $sHyperLinkFilter '';     
  542.         $sHyperLinkIDs '';
  543.         if(count($aHyperLink) > 0
  544.         {                     
  545.             $sHyperLinkIDs implode(''$aHyperLink[0]);              
  546.         }
  547.         
  548.         if(!empty($sHyperLinkIDs))
  549.             $sHyperLinkFilter ' and rc.id not in (' $sHyperLinkIDs ')';                  
  550.     
  551.         $sBibleStr '(';
  552.         $nBibleTransID $request->getSession()->get('current_bible_translation_id');
  553.         if($nBibleTransID != '')        
  554.                $sBibleStr .= 'case when trans.id = ' $nBibleTransID ' then 1 else ';
  555.                
  556.            if($bLangStr)        
  557.                $sBibleStr .= 'case when trans.language_id = ' $language_id ' then 2 else ';    
  558.                 
  559.         $sBibleStr .= 'case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then case when trans.languagedefault then 3 else 4 end end';
  560.         if($nBibleTransID != '')        
  561.                $sBibleStr .= ' end';
  562.                
  563.            if($bLangStr)        
  564.                $sBibleStr .= ' end';
  565.         
  566.         $sBibleStr .= ')';
  567.         
  568.         $sWorkStr '(case when trans.id = ' $translation_id ' then 1 else ';                       
  569.            if($bLangStr)        
  570.                $sWorkStr .= 'case when trans.language_id = ' $language_id ' then 2 else ';    
  571.                 
  572.         $sWorkStr .= 'case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then case when trans.islanguagedefault then 3 else 4 end end end';
  573.                        
  574.            if($bLangStr)        
  575.                $sWorkStr .= ' end';    
  576.         
  577.         $sWorkStr .= ')';
  578.     
  579.         $sSql "select t3.* from "
  580.                 ." (select * from (SELECT distinct on (tc.textunit_id, rc.id) tc.textunit_id, rc.id as ref_id, rc.originallinktext as link_text, cc1.book_id, rb.startverse_id as startloc_id, rb.endverse_id as endloc_id, true as is_bibleref, '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc1.ordering || (case when cc1.id <> cc2.id then '-' || cc2.ordering else '' end) || '_' || cv1.ordering || (case when rb.startverse_id <> rb.endverse_id then '-' || cv2.ordering else '' end) as multilink_text, cc1.ordering as ordering1, cv1.ordering as ordering2, " $sBibleStr " as priority_order, cb.url as book_url, trans.url as trans_url, cc1.ordering as chapter_order1, cc2.ordering as chapter_order2, cv1.ordering as verse_order1, cv2.ordering as verse_order2, trans.url as div_url, 0 as passage_order"
  581.                 ."  FROM refbible rb, refcombined rc, textunit_combinedreference tc, expositiontextunit t, canonicalbibleverse cv1, canonicalbiblechapter cc1, canonicalbiblebook cb, canonicalbibleverse_bibleverse cbb1, bibleverse v1, biblechapter c1, canonicalbibleverse cv2, canonicalbiblechapter cc2, biblebook b, bibletranslation trans"
  582.                 ." WHERE t.passage_id = " $passage_id " and t.id = tc.textunit_id and rc.id = tc.combinedreference_id " $sHyperLinkFilter " and rb.container_id = rc.id and cv1.id = rb.startverse_id and cv1.chapter_id = cc1.id and cc1.book_id = cb.id and cv1.id = cbb1.canonicalbibleverse_id and v1.id = cbb1.bibleverse_id and v1.chapter_id = c1.id and c1.book_id = b.id and cv2.id = rb.endverse_id and cv2.chapter_id = cc2.id and b.translation_id = trans.id and trans.enabled order by tc.textunit_id, rc.id, priority_order asc, trans.languagedefault desc) as b"  
  583.                 ." union"
  584.                 ." select * from (SELECT distinct on (tc.textunit_id, rc.id) tc.textunit_id, rc.id as ref_id, rc.originallinktext as link_text, d.work_id as book_id, re.startlocation_id as startloc_id, re.endlocation_id as endloc_id, false as is_bibleref, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "_' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "_' end) || trans.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as multilink_text, p.ordering as ordering1, t2.ordering as ordering2, " $sWorkStr " as priority_order, trans.url as book_url, trans.url as trans_url, 0 as chapter_order1, 0 as chapter_order2, 0 as verse_order1, 0 as verse_order2, d.url as div_url, p.ordering as passage_order"
  585.                 ." FROM refexposition re, refcombined rc, textunit_combinedreference tc, expositiontextunit t, expositiontextunit t2, expositionpassage p, expositiondivision d, expositionwork w, expositiontranslation trans, expositiontranslationtext tt"
  586.                 ." WHERE t.passage_id = " $passage_id " and t.id = tc.textunit_id and rc.id = tc.combinedreference_id " $sHyperLinkFilter " and re.container_id = rc.id and t2.id = re.startlocation_id and p.id = t2.passage_id and d.id = p.division_id and d.work_id = w.id and w.id = trans.work_id and trans.url is not null and trans.ispublic and w.ispublic and t2.id = tt.placement_id and trans.id = tt.translation_id order by tc.textunit_id, rc.id, priority_order asc, trans.islanguagedefault desc, trans.isoriginal desc) as e";
  587.                 
  588.                 if($bCheck)
  589.                       $sSql .= " limit 1";
  590.                       
  591.                 $sSql .= ") as t3 order by split_part(link_text, ' ', 1), book_id, ordering1, ordering2";
  592.   //   echo $sSql."<br>";   
  593.            $aRet $this->getNativeQueryResults($sSql);  
  594.            $aTemp $aRet;
  595.            $nLen count($aRet);
  596.            for($i=0;$i<$nLen;$i++)
  597.            {
  598.                if($i && $aRet[$i]["textunit_id"] == $aRet[$i-1]["textunit_id"] && $aRet[$i]["book_id"] == $aRet[$i-1]["book_id"] && $aRet[$i]["is_bibleref"] == $aRet[$i-1]["is_bibleref"])
  599.                {
  600.                    $sLink $aRet[$i]["link_text"];              
  601.                    $sPrevLink $aTemp[$i-1]["link_text"];                       
  602.                    $aRet[$i]["link_text"] = $this->removeRepeatStrForRef($sLink$sPrevLink);
  603.                }
  604.                else
  605.                {               
  606.                    if(!empty($language_id) && $language_id != $this->LANGUAGE_ID_ENGLISH)
  607.                    {                   
  608.                        // check book names in other languages
  609.                        if($aRet[$i]["is_bibleref"])
  610.                            $aRet[$i]["link_text"] = $this->getBibleBookName($aRet[$i]["link_text"], $aRet[$i]["book_id"], $language_id);
  611.                        else
  612.                            $aRet[$i]["link_text"] = $this->getWorkBookName($aRet[$i]["link_text"], $aRet[$i]["book_id"], $language_id);    
  613.                    }
  614.                }
  615.                
  616.                $aRet[$i]["link_text"] = str_replace('_'' '$aRet[$i]["link_text"]);
  617.                
  618.                $aRet[$i]["singlelink"] = '';
  619.                if($aRet[$i]["is_bibleref"])
  620.                {
  621.                    if($aTemp[$i]["chapter_order1"] != $aTemp[$i]["chapter_order2"])
  622.                    {                       
  623.                        $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_chapter_verse_range', array(
  624.                         'translationUrl' => $aTemp[$i]["trans_url"],
  625.                         'bookUrl' => $aTemp[$i]["book_url"],
  626.                         'chapterStartIndex' => $aTemp[$i]["chapter_order1"],
  627.                         'chapterEndIndex' => $aTemp[$i]["chapter_order2"],
  628.                         'verseStartIndex' => $aTemp[$i]["verse_order1"],
  629.                         'verseEndIndex' => $aTemp[$i]["verse_order2"]
  630.                     ));                       
  631.                    }
  632.                    else
  633.                    {
  634.                        if($aTemp[$i]["verse_order1"] != $aTemp[$i]["verse_order2"])
  635.                        {
  636.                            $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_verse_range', array(
  637.                             'translationUrl' => $aTemp[$i]["trans_url"],
  638.                             'bookUrl' => $aTemp[$i]["book_url"],
  639.                             'chapterIndex' => $aTemp[$i]["chapter_order1"],
  640.                             'verseStartIndex' => $aTemp[$i]["verse_order1"],
  641.                             'verseEndIndex' => $aTemp[$i]["verse_order2"]
  642.                         )); 
  643.                     }
  644.                     else
  645.                     {
  646.                         $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_verse', array(
  647.                             'translationUrl' => $aTemp[$i]["trans_url"],
  648.                             'bookUrl' => $aTemp[$i]["book_url"],
  649.                             'chapterIndex' => $aTemp[$i]["chapter_order1"],
  650.                             'verseIndex' => $aTemp[$i]["verse_order1"]
  651.                         ));
  652.                     }   
  653.                    }
  654.                }
  655.                else
  656.                {
  657.                    $aRet[$i]["singlelink"] = $this->get('router')->generate('exposition_translation_division_passage', array(
  658.                         'translationUrl' => $aTemp[$i]["trans_url"],
  659.                         'divisionUrls' => $aTemp[$i]["div_url"],
  660.                         'passageNumber' => $aTemp[$i]["passage_order"]
  661.                     )); 
  662.                }
  663.            }
  664.        //    print_r($aRet);  
  665.         return $aRet
  666.         
  667.         // For this task: Test turning off the code that looks for and displays the missing links under 
  668.         // swedenborg sections. See if we get a speed improvement.
  669.         // comment out the above block in this function and add:
  670.         
  671.         // Task: Don't show the textunit refs for all works. (8/4/2021)
  672.         // Don't show the textunit refs for all swedenborg works. Show them for explanations.
  673.         // return array();
  674.     }
  675.     
  676.     public function removeRepeatStrForRef($vLink$vPrevLink)
  677.     {
  678.         $sRet $vLink;
  679.         $aLink explode(' ',$vLink);
  680.         $nLinkNum count($aLink);
  681.         $aPrevLink explode(' ',$vPrevLink);
  682.         $nPrevLinkNum count($aPrevLink);        
  683.         $nDiffStr = -1;
  684.         if($nPrevLinkNum <= $nLinkNum)
  685.         {
  686.             
  687.             for($i=0;$i<$nLinkNum;$i++)
  688.             {
  689.                 if($i $nPrevLinkNum-1)
  690.                     break;
  691.             
  692.                 $sPrevLinkStr trim($aPrevLink[$i]);
  693.                 $sLinkStr trim($aLink[$i]);
  694.                 $sFirstLinkChar substr($sLinkStr01);            
  695.                 if($sPrevLinkStr != $sLinkStr && (is_numeric($sFirstLinkChar) || $sFirstLinkChar == '['))
  696.                 {
  697.                     $nDiffStr $i;
  698.                     break;
  699.                 }        
  700.             }                
  701.         }
  702.         else
  703.         {            
  704.             for($i=0;$i<$nPrevLinkNum;$i++)
  705.             {
  706.                 if($i $nLinkNum-1)
  707.                     break;
  708.             
  709.                 $sPrevLinkStr trim($aPrevLink[$i]);
  710.                 $sLinkStr trim($aLink[$i]);
  711.                 $sFirstLinkChar substr($sLinkStr01);            
  712.                 if($sPrevLinkStr != $sLinkStr && (is_numeric($sFirstLinkChar) || $sFirstLinkChar == '['))
  713.                 {
  714.                     $nDiffStr $i;
  715.                     break;
  716.                 }
  717.             }                    
  718.         }
  719.         
  720.         if($nDiffStr 0)
  721.         {
  722.             $sRet '';
  723.             for($i=$nDiffStr;$i<$nLinkNum;$i++)
  724.             {
  725.                 if($sRet != '')
  726.                     $sRet .= ' ';
  727.             
  728.                 $sRet .= $aLink[$i];
  729.             }
  730.         }
  731.         return $sRet;
  732.     }
  733.     
  734.     public function getRefName($vLink)
  735.     {
  736.         $sRet '';
  737.         $sTempLink str_replace(" [""["$vLink);
  738.         $nPos strrpos($sTempLink' ');
  739.         if($nPos > -1)
  740.         {
  741.             $sRet substr($sTempLink0$nPos);
  742.         }
  743.         return $sRet;
  744.     }
  745.     
  746.     public function removeRefName($vLink$vName)
  747.     {
  748.         $sRet trim(str_replace($vName''$vLink));
  749.         return $sRet;
  750.     }
  751.     
  752.     function getWorkPassageMultiLink($passage_id,$translation_id$request)
  753.     {        
  754.         $aRet = array();
  755.         
  756.         $sBibleStr '';
  757.         $nBibleTransID $request->getSession()->get('current_bible_translation_id');
  758.         if($nBibleTransID != '')
  759.         {
  760.                $sBibleStr '(case when trans.id = ' $nBibleTransID ' then 1 else case when trans.language_id in (select language_id from expositiontranslation where id = ' $translation_id ') then 2 else case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 3 else 4 end end end)';
  761.         }
  762.         else
  763.         {
  764.             $sBibleStr '(case when trans.language_id in (select language_id from expositiontranslation where id = ' $translation_id ') then 1 else case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else 3 end end )';
  765.         }
  766.         
  767.         // section_order is used for exposition references only
  768.         $sSql "select * from (SELECT distinct on (di.ref_id) di.ref_id, '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc1.ordering || (case when cc1.id <> cc2.id then '-' || cc2.ordering else '' end) || '_' || cv1.ordering || (case when rb.startverse_id <> rb.endverse_id then '-' || cv2.ordering else '' end) as multilink, true as is_bibleref, 1 as section_order, " $sBibleStr " as priority_order, cb.url as book_url, trans.url as trans_url, cc1.ordering as chapter_order1, cc2.ordering as chapter_order2, cv1.ordering as verse_order1, cv2.ordering as verse_order2, trans.url as div_url, 0 as passage_order"
  769.                 ." FROM refbible rb, expositiontextunit t, expositiontranslationtext tt, expositiondisplayitem di, canonicalbibleverse cv1, canonicalbiblechapter cc1, canonicalbiblebook cb, canonicalbibleverse cv2, canonicalbiblechapter cc2, biblebook b, bibletranslation trans "
  770.                 ." WHERE t.passage_id = " $passage_id " and t.id = tt.placement_id and rb.container_id = di.ref_id and di.container_id = tt.id and di.ref_id is not null and cv1.id = rb.startverse_id and cv1.chapter_id = cc1.id and cc1.book_id = cb.id and cv2.id = rb.endverse_id and cv2.chapter_id = cc2.id and b.canonicalization_id = cb.id and b.translation_id = trans.id and trans.enabled order by di.ref_id, priority_order asc, trans.languagedefault desc) as b"  
  771.                 ." union"
  772.                 ." select * from (SELECT distinct on (di.ref_id) di.ref_id, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || trans.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as multilink, false as is_bibleref, t2.ordering as section_order,  (case when trans.id = " $translation_id " then 1 else case when trans.language_id in (select language_id from expositiontranslation where id = " $translation_id ") then 2 else case when trans.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3 else 4 end end end) as priority_order, trans.url as book_url, trans.url as trans_url, 0 as chapter_order1, 0 as chapter_order2, 0 as verse_order1, 0 as verse_order2, d.url as div_url, p.ordering as passage_order"
  773.                 ." FROM refexposition re, expositiontextunit t, expositiontextunit t2, expositionpassage p, expositiondivision d, expositiontranslationtext tt, expositiondisplayitem di, expositionwork w, expositiontranslation trans"
  774.                 ." WHERE t.passage_id = " $passage_id " and t2.id = re.startlocation_id and p.id = t2.passage_id and d.id = p.division_id and re.container_id = di.ref_id and t.id = tt.placement_id and di.container_id = tt.id and di.ref_id is not null and d.work_id = w.id and w.id = trans.work_id and trans.url is not null and trans.ispublic and w.ispublic order by di.ref_id, priority_order asc, trans.islanguagedefault desc, trans.isoriginal desc) as e";
  775.   //   echo $sSql."<br>";   
  776.            $aTemp $this->getNativeQueryResults($sSql);  
  777.            $nLen count($aTemp);           
  778.            for($i=0;$i<$nLen;$i++)
  779.            {      
  780.                $aRef = array();
  781.                $aRef["multilink"] = $aTemp[$i]["multilink"];
  782.                $aRef["is_bibleref"] = $aTemp[$i]["is_bibleref"];
  783.                
  784.                $aRef["singlelink"] = '';
  785.                if($aRef["is_bibleref"])
  786.                {
  787.                    if($aTemp[$i]["chapter_order1"] != $aTemp[$i]["chapter_order2"])
  788.                    {                       
  789.                        $aRef["singlelink"] = $this->get('router')->generate('bible_chapter_verse_range', array(
  790.                         'translationUrl' => $aTemp[$i]["trans_url"],
  791.                         'bookUrl' => $aTemp[$i]["book_url"],
  792.                         'chapterStartIndex' => $aTemp[$i]["chapter_order1"],
  793.                         'chapterEndIndex' => $aTemp[$i]["chapter_order2"],
  794.                         'verseStartIndex' => $aTemp[$i]["verse_order1"],
  795.                         'verseEndIndex' => $aTemp[$i]["verse_order2"]
  796.                     ));                       
  797.                    }
  798.                    else
  799.                    {
  800.                        if($aTemp[$i]["verse_order1"] != $aTemp[$i]["verse_order2"])
  801.                        {
  802.                            $aRef["singlelink"] = $this->get('router')->generate('bible_verse_range', array(
  803.                             'translationUrl' => $aTemp[$i]["trans_url"],
  804.                             'bookUrl' => $aTemp[$i]["book_url"],
  805.                             'chapterIndex' => $aTemp[$i]["chapter_order1"],
  806.                             'verseStartIndex' => $aTemp[$i]["verse_order1"],
  807.                             'verseEndIndex' => $aTemp[$i]["verse_order2"]
  808.                         )); 
  809.                     }
  810.                     else
  811.                     {
  812.                         $aRef["singlelink"] = $this->get('router')->generate('bible_verse', array(
  813.                             'translationUrl' => $aTemp[$i]["trans_url"],
  814.                             'bookUrl' => $aTemp[$i]["book_url"],
  815.                             'chapterIndex' => $aTemp[$i]["chapter_order1"],
  816.                             'verseIndex' => $aTemp[$i]["verse_order1"]
  817.                         ));
  818.                     }   
  819.                    }
  820.                }
  821.                else
  822.                {
  823.                    $aRef["singlelink"] = $this->get('router')->generate('exposition_translation_division_passage', array(
  824.                         'translationUrl' => $aTemp[$i]["trans_url"],
  825.                         'divisionUrls' => $aTemp[$i]["div_url"],
  826.                         'passageNumber' => $aTemp[$i]["passage_order"]
  827.                     )); 
  828.                }
  829.                
  830.                $aRef["section_order"] = $aTemp[$i]["section_order"];
  831.                $aRet[$aTemp[$i]["ref_id"]] = $aRef;
  832.            } 
  833.              
  834.         return $aRet
  835.     }
  836.     
  837.     function getBibleTranslationsByLanguage($canonical_book_id=null$language_id=null)
  838.     {            
  839.         $sGroupOrder $this->getGroupOrderForBibleTranslation($language_id);
  840.         
  841.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name as name, t.url, bk.url as first_book_url, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as group_name, " $sGroupOrder " as group_order, true as has_book, true as has_chapter"
  842.                 ." FROM language l, bibletranslation t"
  843.                 ." join ("
  844.                 ." select distinct on (t2.id) t2.id as translation_id, cb.url"
  845.                 ." from bibletranslation t2, biblebook b, canonicalbiblebook cb where b.translation_id = t2.id and cb.id = b.canonicalization_id"                
  846.                 ." order by t2.id, b.ordering"
  847.                 .") as bk on t.id = bk.translation_id";
  848.                 
  849.       $sSql .= " WHERE t.enabled and t.language_id = l.id";  
  850.                       
  851.       if($canonical_book_id != null)
  852.       {          
  853.           $sSql .= " and t.id in (select distinct translation_id from biblebook where canonicalization_id = " $canonical_book_id ")";
  854.       }   
  855.                     
  856.       $sSql .= " order by group_order, language_name, t.name";
  857.  //    echo $sSql."<br>";   
  858.            return $this->getNativeQueryResults($sSql);  
  859.     }
  860.             
  861.     function getBibleRefPassage($aVerseInfo$bChapter$bCorePassage=false$bCheck=false)
  862.     {            
  863.         if(empty($aVerseInfo))
  864.             return array();
  865.         
  866.         $canon = array();
  867.         $nulls = array();
  868.         $verseLanguage null;        
  869.         $sVerseIDs $aVerseInfo['CVerseIDs'];
  870.         $verseLanguage $aVerseInfo['LanguageID'];
  871.         
  872.         if($verseLanguage == '')
  873.             $verseLanguage $this->LANGUAGE_ID_ENGLISH;
  874.                   
  875.         $sCChapterIDs '';
  876.         if($bChapter)
  877.             $sCChapterIDs $aVerseInfo['CChapterIDs'];   
  878.     
  879.         if($sVerseIDs == '' && $sCChapterIDs == '') {
  880.             return null;
  881.         } else {           
  882.             if($sVerseIDs != '')
  883.             {      
  884.                 $tempChapterIDs $this->checkWholeChapters($sVerseIDs);
  885.                 if($tempChapterIDs != null)
  886.                 {
  887.                     if($sCChapterIDs != '')
  888.                         $sCChapterIDs .= ',';
  889.                     
  890.                     $sCChapterIDs .= $tempChapterIDs
  891.                 }    
  892.             }                     
  893.         
  894.             return $this->getBibleRefPassageInfo($verseLanguage$sVerseIDs$sCChapterIDs$bCorePassage$bCheck);
  895.         }
  896.     } 
  897.     
  898.     function checkWholeChapters($sVerseIDs)
  899.     {
  900.         if($sVerseIDs == '')
  901.             return '';
  902.         
  903.         $sAllChapterIDs '';
  904.         $sSql "select array_to_string(array_agg(distinct chapter_id), ',') from canonicalbibleverse where id in (" $sVerseIDs ")";
  905.  //  echo $sSql."<br>";        
  906.         $aTemp $this->getNativeQueryResults($sSql);
  907.         if(count($aTemp) > 0
  908.         {            
  909.             $sAllChapterIDs implode(","$aTemp[0]);
  910.         } 
  911.         
  912.         $sSql "select array_to_string(array_agg(id), ',') from canonicalbiblechapter where id in (" $sAllChapterIDs ") and id not in (select distinct chapter_id from canonicalbibleverse where chapter_id in (" $sAllChapterIDs ") and id not in (" $sVerseIDs "))";
  913.  //  echo $sSql."<br>";
  914.         $aTemp $this->getNativeQueryResults($sSql);                
  915.         $sRet '';                
  916.         if(count($aTemp) > 0
  917.         {            
  918.             $sRet implode(","$aTemp[0]);
  919.         }
  920.                 
  921.         return $sRet;
  922.     }
  923.     
  924.     function getBibleRefPassageInfo($language_id$sVerseIDs$sChapterIDs$bCorePassage$bCheck)
  925.     {            
  926.         if($sVerseIDs == '' && $sChapterIDs == ''
  927.             return array();
  928.             
  929.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English    
  930.                     
  931.         $sFilter " p.id";
  932.          if(!$bCorePassage)
  933.           {
  934.               $sFilter .= " in (";
  935.                                   
  936.             if ($sVerseIDs <> '')
  937.             {
  938.                $sFilter .= 'SELECT DISTINCT passage_id FROM verse_passage'
  939.                     .' WHERE  verse_id in (' $sVerseIDs ')';
  940.             }
  941.               $sFilter .= ") and p.id not ";
  942.           }   
  943.           
  944.           $sFilter .= " in (";
  945.           
  946.         if ($sChapterIDs <> '')
  947.         {
  948.             $sFilter .= 'SELECT DISTINCT passage_id FROM chapter_passage'
  949.                 .' WHERE chapter_id in (' $sChapterIDs ')';         
  950.         }
  951.         
  952.         if ($sVerseIDs <> '')
  953.         {
  954.             if ($sChapterIDs <> '')
  955.                  $sFilter .= " union ";
  956.         
  957.            $sFilter .= 'SELECT DISTINCT passage_id FROM verse_passage'
  958.                 .' WHERE  verse_id in (' $sVerseIDs ')';    
  959.                 $sFilter .= ' and iscorepassage';
  960.         }        
  961.         $sFilter .= ")";    
  962.         
  963.         $sSql "select * from (SELECT distinct on (p.id) p.id, w.swedenborgtype, t.translatedtitle AS title, p.swedenborgsection as num, '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as ref_column_spec, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering, case when t.language_id = " $language_id " then 1 else 2 end as lang_order"
  964.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  965.                 ." WHERE " $sFilter;          
  966.           $sSql .= " and w.swedenborgtype is not null and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (";
  967.           
  968.           $sSql .= "SELECT distinct on (w.id) t.id"
  969.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  970.                 ." WHERE " $sFilter;          
  971.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id in ( ".$language_id"," $nDefaultLanguageID ") and t.ispublic and w.ispublic and t.url is not null and t.url <> ''";
  972.           $sSql .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  973.           $sSql .= " order by w.id, t.islanguagedefault desc"
  974.           
  975.           if($bCheck)
  976.               $sSql .= " limit 1";
  977.               
  978.           $sSql .= ") order by p.id, lang_order";    
  979.                         
  980.           $sSql .= ") as t2 order by work_order, title, ordering";
  981.   //   echo $sSql."<br>";
  982.            return $this->getNativeQueryResults($sSql);  
  983.     }
  984.     
  985.     function getVerseConcept($verses$language_id)
  986.     {         
  987.         $aRet = array();
  988.         $aTemp = array();
  989.         if($verses != null && !empty($verses))
  990.         {       
  991.         //    $language_id = null;
  992.             $sVerseIDs '';
  993.             foreach($verses as $verse)
  994.             {
  995.                 if($sVerseIDs != '')
  996.                     $sVerseIDs .= ',';
  997.             
  998.                 $sVerseIDs .= $verse->getId();
  999.                 
  1000.             /*    if($language_id == null)
  1001.                     $language_id = $verse->findMainVerse()->getChapter()->getBook()->getTranslation()->getLanguage()->getId(); */
  1002.             }
  1003.                                     
  1004.             if($sVerseIDs != '' && $language_id != null)
  1005.             {
  1006.                 $sBorderStr $this->getBoundaryStrForSql($language_id);
  1007.             
  1008.                 $sSql "select * from (SELECT distinct on (verse_id, term_text) * from (select cbb.bibleverse_id as verse_id, t.id as term_id, lower(t.text) as term_text, c.url as concept_url, char_length(t.text) as text_len, ct.translatedtitle as title, ct.explanation_id, c.id as concept_id"
  1009.                         ." FROM verse_concept vc, term_concept tc, term t, concept c, (select * from canonicalbibleverse_bibleverse where bibleverse_id in (" $sVerseIDs ")) as cbb, bibleverse bv,";
  1010.                         
  1011.                 if($language_id == $this->LANGUAGE_ID_ENGLISH)  
  1012.                 {      
  1013.                     $sSql .= " (select distinct on (cl.concept_id) cl.concept_id, trans.translatedtitle, trans.id as explanation_id from concept_work cl, expositiontranslation trans where trans.language_id = " $language_id " and cl.work_id = trans.work_id) as ct ";
  1014.                 }
  1015.                 else
  1016.                 {
  1017.                     $sSql .= " (select distinct on (cl.concept_id) cl.concept_id, trans.translatedtitle, trans.id as explanation_id, case when trans.language_id = " $language_id " then 1 else 2 end as ordering from concept_work cl, expositiontranslation trans where trans.language_id in (" $language_id ", " $this->LANGUAGE_ID_ENGLISH ") and cl.work_id = trans.work_id order by cl.concept_id, ordering) as ct ";
  1018.                 }
  1019.                 
  1020.                 $sSql .= " WHERE cbb.canonicalbibleverse_id = vc.verse_id and tc.concept_id = vc.concept_id and t.id = tc.term_id and c.id = tc.concept_id and t.language_id = " $language_id " and ct.concept_id = c.id";   
  1021.                 $sSql .= " and cbb.bibleverse_id = bv.id and case when t.text is not null and (bv.content ~* ('" $sBorderStr "' || " $this->EscapeTextForRegex("t.text") . " || '" $sBorderStr "')) then true else false end order by cbb.bibleverse_id, lower(t.text), term_id) as t1) as t order by verse_id, char_length(term_text) desc";                      
  1022.           //   echo $sSql."<br>";
  1023.                    $aTemp $this->getNativeQueryResults($sSql); 
  1024.                }
  1025.            }
  1026.            
  1027.            foreach($aTemp as $temp)
  1028.            {
  1029.                $aRet[$temp['verse_id']][] = $temp;
  1030.            }
  1031.            
  1032.            return $aRet;
  1033.     }
  1034.     
  1035.     /*
  1036.      * Finds concept references in the text, and insert concept links to the text.
  1037.      * Returns the verse text with concept links.
  1038.      */
  1039.     public function getVerseContentWithConceptLinks($request$verses$bibleColumnSpec$column_number=0)
  1040.     {        
  1041.         $bOnMobile $this->isOnMobile();
  1042.         
  1043.         $sConceptMark "qmrgyx";    
  1044.         $sHyphenMark "xhfvkw";     
  1045.         $sSpaceMark "zszkrx";
  1046.         $sConceptLinkMark "2";
  1047.         
  1048.         $language_code null;            
  1049.         $language_id null;       
  1050.         foreach($verses as $verse)
  1051.         {                        
  1052.             if($language_code == null)
  1053.             {
  1054.         /*        $lang = $verse->findMainVerse()->getChapter()->getBook()->getTranslation()->getLanguage();
  1055.                 $language_code = $lang->getBibliographicCode();
  1056.                 $language_id = $lang->getId(); */
  1057.                 
  1058.                 $aLang $this->getVerseData($verse->getId());
  1059.                 $language_code $aLang['bibliographiccode'];
  1060.                 $language_id $aLang['language_id'];
  1061.                 break;
  1062.             }    
  1063.         }
  1064.         
  1065.         // For Malayalam and Tagalog, page loads tend to be slow, perhaps because of bandwidth. 
  1066.         // We could try turning off commentary and word highlighting
  1067.         // We can set it on the language list on the admin site
  1068.         if(!$this->showBibleHighlights($language_id))
  1069.         {
  1070.             return array();
  1071.         }
  1072.         
  1073.         $bShowBibleLinks true;
  1074.         $nShowBibleLinks $request->getSession()->get('show_bible_links');
  1075.         if($nShowBibleLinks == 2)
  1076.             $bShowBibleLinks false;
  1077.         
  1078.         if(!$bShowBibleLinks)
  1079.         {
  1080.             return array();
  1081.         }    
  1082.         
  1083.         $conceptPopupLink $this->get('router')->generate('popover_concept', array(
  1084.                     'explanationID' => $sConceptLinkMark,
  1085.                     'conceptID' => $sConceptLinkMark
  1086.                 ));     
  1087.         $conceptPopupLink rtrim($conceptPopupLink$sConceptLinkMark."/".$sConceptLinkMark)."/";
  1088.         
  1089.   /*      $conceptLink = $this->get('router')->generate('concept', array(
  1090.                     'conceptUrl' => $sConceptLinkMark
  1091.                 )); */
  1092.         $conceptOverlayLink $this->get('router')->generate('overlay_concept', array(
  1093.                     'conceptUrl' => $sConceptLinkMark
  1094.                 ));        
  1095.    //     $conceptLink = trim($conceptLink, $sConceptLinkMark);
  1096.         $conceptOverlayLink rtrim($conceptOverlayLink$sConceptLinkMark);        
  1097.       
  1098.       // The user requests that we will show modals on mobile devices now (10/19/2020)  
  1099.      //   if(!$bOnMobile)
  1100.         if(true)
  1101.         {
  1102.             $sLanguageStr '';
  1103.             if($language_code != 'eng')
  1104.                 $sLanguageStr '/'.$language_code;
  1105.             
  1106.             $sBibleStr '';
  1107.             if(!empty($bibleColumnSpec))
  1108.                 $sBibleStr '?b='.$bibleColumnSpec;    
  1109.         }    
  1110.         
  1111.         // Some languages have no space between words    
  1112.         $sBorderStr $this->getBoundaryStrForPhp($language_id);    
  1113.                
  1114.         if($bOnMobile)
  1115.         {               
  1116.                // don't show popover on mobiles
  1117.                $sLink1a "<a ";
  1118.        //        if(!$bShowBibleLinks)
  1119.         //         $sLink1a .= " style='display:none' ";
  1120.                  
  1121.             $sLinkMark1a "lll1a";
  1122.                     
  1123.             $sLink1 " href='javascript:sm(\"";
  1124.             $sLinkMark1 "lll1";
  1125.             
  1126.         //    $sLink2 = "','" . $conceptLink;
  1127.         //    $sLinkMark2 = "lll2";
  1128.             $sLink3 "\",\"" $conceptOverlayLink;
  1129.             $sLinkMark3 "lll3";      
  1130.             $sLink4 "\")' >";     
  1131.         }
  1132.         else
  1133.         {        
  1134.             $sLink1a "<a ";
  1135.         //    if(!$bShowBibleLinks)
  1136.         //         $sLink1a .= " style='display:none' ";
  1137.                  
  1138.             $sLink1a .= " data-poload='" $conceptPopupLink;     
  1139.                     
  1140.             $sLinkMark1a "lll1a";
  1141.                     
  1142.             $sLink1 "' href='javascript:sm(\"";
  1143.             $sLinkMark1 "lll1";
  1144.             
  1145.         //    $sLink2 = "','" . $conceptLink;
  1146.         //    $sLinkMark2 = "lll2";
  1147.             $sLink3 "\",\"" $conceptOverlayLink;
  1148.             $sLinkMark3 "lll3";      
  1149.             $sLink4 "\")' data-placement='auto' >";      
  1150.         }
  1151.                 
  1152.         $sLinkMark4 "lll4";    
  1153.         $sLink5 "</a>";    
  1154. /*           $sLink5 = "</a><span ";
  1155.         if($bShowBibleLinks)
  1156.              $sLink5 .= " style='display:none'";
  1157.             
  1158.         $sLink5 .= " >";     */
  1159.              
  1160.         $sLinkMark5 "lll5";            
  1161.     //    $sLink6 = "</span>";
  1162.     //    $sLinkMark6 = "lll6";
  1163.                 
  1164.         $sTermIDMark "tt";
  1165.         $sPopupStartMark "~ppss~";
  1166.         $sPopupEndMark "~ppee~";
  1167.         $aRet = array();        
  1168.         $aTerm $this->getVerseConcept($verses$language_id);
  1169.  
  1170.         $nLen count($aTerm);        
  1171.         foreach($verses as $verse)
  1172.         {
  1173.             $aTermFromText = array();
  1174.             $aTermTitle = array();
  1175.             $text $verse->getContent();    
  1176.             // replace popup code
  1177.             preg_match_all('/'.$sPopupStartMark.'[^~]+'.$sPopupEndMark.'/ui'$text$matches1);
  1178.       //      print_r($matches1[0]);
  1179.             $aPopup $matches1[0];
  1180.             if(!empty($aPopup))
  1181.             {
  1182.                 $nPopupCount 1;
  1183.                 foreach($aPopup as $popup)
  1184.                 {
  1185.                     $text str_replace($popup$sPopupStartMark.$nPopupCount.$sPopupEndMark$text);
  1186.                     $nPopupCount++;                        
  1187.                 }
  1188.             }
  1189.             $verse_id $verse->getId();
  1190.             if($nLen && array_key_exists($verse_id$aTerm) && !empty($aTerm[$verse_id]))
  1191.             {            
  1192.                 $aTermForV $aTerm[$verse_id];
  1193.                 foreach ($aTermForV as $term)
  1194.                 {                    
  1195.                     $sTempText $term['term_text'];                            
  1196.                     preg_match_all('/'.$sBorderStr.''.preg_quote($sTempText'/').$sBorderStr.'/ui'$text$matches2);
  1197.                     $aText2 array_unique($matches2[0]);
  1198.         //    print_r($aText2);        
  1199.                     $nCount2=0;
  1200.                     foreach ($aText2 as &$sSearch)
  1201.                     {                        
  1202.                         $sTempKey $term['term_id'].'@'.$nCount2;    
  1203.                         $aTermFromText[$sTempKey] = $sSearch;    
  1204.                         $aTermTitle[$sTempKey] = $term['title'];                                    
  1205.                 //        str_replace($sSearch,$sTermIDMark.$sTempKey.$sTermIDMark, $text);
  1206.                 
  1207.                         $pattern '/'.$sBorderStr.''.preg_quote($sSearch'/').$sBorderStr.'/ui';
  1208.                         $text preg_replace($pattern$sTermIDMark.$sTempKey.$sTermIDMark$text);
  1209.                         
  1210.                         $nCount2++;
  1211.                     }
  1212.                 }
  1213.                 
  1214.                 foreach($aTermForV as $term)        
  1215.                 {               
  1216.                     //if($bOnMobile)
  1217.                     if(false)
  1218.                     {
  1219.                         $sTermID $sConceptMark.$term['term_id'].$sConceptMark;
  1220.                         $sNewText $sLinkMark1 $sTermID "," $column_number $sLinkMark4 "$1" $sLinkMark5;
  1221.                                             
  1222.                         $text preg_replace('/'.$sBorderStr.'('.$sTermIDMark.$term['term_id']."@\d+".$sTermIDMark.')'.$sBorderStr.'/ui',$sNewText$text);                        
  1223.                     }
  1224.                     else
  1225.                     {                                                
  1226.                         $sConceptUrl $sConceptMark.$term['concept_url'].$sConceptMark;
  1227.                         $sConceptUrl str_replace('-'$sHyphenMark$sConceptUrl);
  1228.                         $nExplanationID $term['explanation_id'];
  1229.                         $conceptID $term['concept_id'];
  1230.                         if($bOnMobile)
  1231.                             $sNewText $sLinkMark1a $sLinkMark1 "$1" $sLinkMark3 $sConceptUrl $sLanguageStr $sBibleStr $sLinkMark4 "$1" $sLinkMark5;
  1232.                         else
  1233.                             $sNewText $sLinkMark1a $nExplanationID "/" $conceptID $sLinkMark1 "$1" $sLinkMark3 $sConceptUrl $sLanguageStr $sBibleStr $sLinkMark4 "$1" $sLinkMark5;
  1234.                         $text preg_replace('/'.'('.$sTermIDMark.$term['term_id']."@\d+".$sTermIDMark.')'.'/i',$sNewText$text);    
  1235.                     }            
  1236.                     
  1237.                 }  
  1238.                             
  1239.                 $text str_replace($sConceptMark,''$text);
  1240.                 $text str_replace($sHyphenMark,'-'$text);
  1241.                 $text str_replace($sSpaceMark,' '$text);
  1242.                 
  1243.             //    if(!$bOnMobile)
  1244.                     $text str_replace($sLinkMark1a$sLink1a$text);
  1245.                 
  1246.                 $text str_replace($sLinkMark1$sLink1$text);
  1247.             //    $text = str_replace($sLinkMark2, $sLink2, $text);
  1248.                 
  1249.         //        if(!$bOnMobile)    
  1250.         //        {
  1251.                     foreach ($aTermTitle as $key3 =>$term3)
  1252.                     {        
  1253.                         $term3 str_replace("'""~q~",$term3);    
  1254.                         $text str_replace($sTermIDMark.$key3.$sTermIDMark.$sLinkMark3,$term3.$sLinkMark3$text);        
  1255.                     }
  1256.         //        }
  1257.                 
  1258.                 foreach ($aTermFromText as $key3 =>$term3)
  1259.                 {    
  1260.                     //$term3 = str_replace("'", "\'",$term3);
  1261.                     $text str_replace($sTermIDMark.$key3.$sTermIDMark,$term3$text);
  1262.                 }
  1263.                 
  1264.             //    if(!$bOnMobile)                                
  1265.                     $text str_replace($sLinkMark3$sLink3$text);
  1266.                                     
  1267.                 $text str_replace($sLinkMark4$sLink4$text);
  1268.                 $text str_replace($sLinkMark5$sLink5$text);    
  1269.             //    $text = str_replace($sLinkMark6, $sLink6, $text);        
  1270.             }
  1271.             
  1272.             if(!empty($aPopup))
  1273.             {
  1274.                 $nPopupCount 1;
  1275.                 foreach($aPopup as $popup)
  1276.                 {
  1277.                     $text str_replace($sPopupStartMark.$nPopupCount.$sPopupEndMark$popup$text);
  1278.                     $nPopupCount++;                    
  1279.                 }
  1280.             }            
  1281.                  
  1282.         //    $text = str_replace('"', "&quot;", $text);
  1283.                                             
  1284.                $text str_replace($sPopupStartMark'<sup><a data-toggle="popover" style="cursor: pointer; color:#007bff;"data-content="'$text);    
  1285.             $text str_replace($sPopupEndMark'">*</a></sup>'$text);
  1286.             
  1287.             $aRet[$verse_id] = $text;            
  1288.         }
  1289.                         
  1290.         return $aRet;
  1291.     }
  1292.     
  1293.     function getBibleTranslationInfo($translation_url$book_url)
  1294.     {                
  1295.         $sSql "SELECT max(c.ordering) as last_chapter_order, t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name as name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, l.id as language_id"
  1296.                 ." FROM language l, bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb" 
  1297.                 ." WHERE t.url = '" trim(str_replace("'""''"$translation_url)) . "' and t.enabled and t.language_id = l.id and b.translation_id = t.id and cb.url = '" trim(str_replace("'""''"$book_url)) . "' "
  1298.                 ." and c.book_id = b.id and b.canonicalization_id = cb.id group by t.id, b.id, cb.id, l.id";
  1299.   //   echo $sSql."<br>";   
  1300.            $aRet = array();
  1301.         $aTemp $this->getNativeQueryResults($sSql);
  1302.         if(count($aTemp) > 0
  1303.             $aRet $aTemp[0];        
  1304.                 
  1305.         return $aRet;   
  1306.     }
  1307.     
  1308.     function getBibleBookList($request$translation_id1$translation_id2=null$translation_id3=null)
  1309.     {                
  1310.         $sOldTestament $request->getSession()->get('ui_str')["bible.testament.oldtestament"];
  1311.         $sNewTestament $request->getSession()->get('ui_str')["bible.testament.newtestament"];
  1312.         $sApocrypha $request->getSession()->get('ui_str')["bible.testament.apocrypha"];
  1313.     
  1314.         $sSql "SELECT b.id, b.name, cb.id as canonical_id, cb.url as canonical_book_url, case when cb.testament_id = " $this->TESTAMENT_OLDTESTAMENT " then '" str_replace("'""''"$sOldTestament) . "' else case when cb.testament_id = " $this->TESTAMENT_NEWTESTAMENT " then '" str_replace("'""''"$sNewTestament) . "' else case when cb.testament_id = " $this->TESTAMENT_APOCRYPHA " then '" str_replace("'""''"$sApocrypha) . "' end end end as testament_name, t.url as translation_url, min(c.ordering) as first_chapter_order, cb.testament_id"
  1315.                 ." FROM biblebook b, biblechapter c, canonicalbiblebook cb, bibletranslation t" 
  1316.                 ." WHERE b.translation_id = " $translation_id1 
  1317.                 ." and b.canonicalization_id = cb.id"
  1318.                 ." and t.id = b.translation_id and c.book_id = b.id";
  1319.                 
  1320.         if($translation_id2 != null
  1321.         {
  1322.             $sSql .= " and cb.id in (SELECT cb.id FROM biblebook b, canonicalbiblebook cb" 
  1323.                 ." WHERE b.translation_id = " $translation_id2 " and b.canonicalization_id = cb.id)";
  1324.         }  
  1325.         
  1326.         if($translation_id3 != null
  1327.         {
  1328.             $sSql .= " and cb.id in (SELECT cb.id FROM biblebook b, canonicalbiblebook cb" 
  1329.                 ." WHERE b.translation_id = " $translation_id3 " and b.canonicalization_id = cb.id)";
  1330.         }    
  1331.         
  1332.         $sSql .= " group by b.id, b.name, cb.id, cb.url, testament_name, t.url";
  1333.         $sSql .= " order by cb.testament_id, cb.id";
  1334.                 
  1335.    //  echo $sSql."<br>";                   
  1336.         return $this->getNativeQueryResults($sSql);   
  1337.     }
  1338.     
  1339.     function getCanonicalBook($bookUrl)
  1340.     {                
  1341.         $sSql "SELECT cb.id, cb.url, array_to_string(array_agg(cc.ordering),',') as chapters"
  1342.                 ." FROM canonicalbiblebook cb, canonicalbiblechapter cc"                
  1343.                 ." WHERE cb.url = '" trim(str_replace("'""''"$book_url)) . "' limit 1";
  1344.  //    echo $sSql;   
  1345.            $aRet = array();
  1346.         $aTemp $this->getNativeQueryResults($sSql);
  1347.         if(count($aTemp) > 0
  1348.             $aRet $aTemp[0];        
  1349.                 
  1350.         return $aRet;   
  1351.     }
  1352.     
  1353.     function getStoriesForVerses($aVerseInfo$request$bCheck=false)
  1354.     {        
  1355.         if(empty($aVerseInfo))
  1356.             return array();
  1357.     
  1358.         $aRet = array();
  1359.         $sVerseIDs $aVerseInfo['VerseIDs'];
  1360.           
  1361.         if($sVerseIDs != '')
  1362.         {    
  1363.             $nUILanguageID $this->getUILanguageID($request);
  1364.             $nPreferredLanguageID $this->getUserPreferredLanguageID($request);
  1365.             
  1366.             $nBookLanguageID $aVerseInfo['LanguageID'];
  1367.             
  1368.             $sLangOrder "case when t.language_id = " $nBookLanguageID " then 1";
  1369.             $sLangFilter " and t.language_id in (" $nBookLanguageID;
  1370.             
  1371.             $sEndStr "";
  1372.             if($nBookLanguageID != $nUILanguageID)
  1373.             {
  1374.                 $sLangOrder .= " else case when t.language_id = " $nUILanguageID " then 2";
  1375.                 $sEndStr .= " end ";
  1376.                 $sLangFilter .= "," $nUILanguageID;
  1377.             }
  1378.             
  1379.             if(!empty($nPreferredLanguageID) && $nBookLanguageID != $nPreferredLanguageID && $nUILanguageID != $nPreferredLanguageID)
  1380.             {
  1381.                 $sLangOrder .= ' else case when t.language_id = ' $nPreferredLanguageID ' then 3';    
  1382.                 $sEndStr .= " end ";
  1383.                 $sLangFilter .= "," $nPreferredLanguageID;
  1384.             }
  1385.                                     
  1386.             if($nBookLanguageID != $this->LANGUAGE_ID_ENGLISH && $nUILanguageID != $this->LANGUAGE_ID_ENGLISH && $nPreferredLanguageID != $this->LANGUAGE_ID_ENGLISH)
  1387.             {
  1388.                 $sLangOrder .= " else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 4";
  1389.                 $sEndStr .= " end ";
  1390.                 $sLangFilter .= "," $this->LANGUAGE_ID_ENGLISH;
  1391.             }
  1392.             
  1393.             $sLangOrder .= $sEndStr " end as lang_order";
  1394.             $sLangFilter .= ")";
  1395.         
  1396.             $sSql "select * from (SELECT distinct on (bs.id) bs.id, bs.url, case when bsl.name is null then bs.name else bsl.name end as name, cv.ordering, t.url as explanation_url, bt.url as bible_translation_url, " $sLangOrder
  1397.                     ." FROM (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE ") as bs, canonicalbibleverse cv, bibleverse v, (select * from canonicalbibleverse_bibleverse where bibleverse_id in (" $sVerseIDs ")) as cvv,"
  1398.                     ." canonicalbiblechapter scc1, canonicalbiblechapter scc2, canonicalbiblechapter vcc," 
  1399.                     ." canonicalbibleverse scv1, canonicalbibleverse scv2, expositiontranslation t, expositionwork w, bibletranslation bt, biblechapter c, biblebook b, story_work sw " 
  1400.                     ." left join (select * from biblestory_language where language_id = " $nBookLanguageID ") as bsl on sw.story_id = bsl.biblestory_id"
  1401.                     ." WHERE t.ispublic and w.ispublic and sw.work_id = w.id"$sLangFilter
  1402.                     ." and v.id = cvv.bibleverse_id and cv.id = cvv.canonicalbibleverse_id"
  1403.                     ." and scv1.id = bs.startverse_id and scv2.id = bs.endverse_id"
  1404.                     ." and scv1.chapter_id = scc1.id and scv2.chapter_id = scc2.id"
  1405.                     ." and vcc.id = cv.chapter_id and v.chapter_id = c.id and c.book_id = b.id and b.translation_id = bt.id"
  1406.                     ." and (bs.startverse_id = cv.id or bs.endverse_id = cv.id"             
  1407.                     ." or (scc1.id = scc2.id and scc1.id = vcc.id and cv.ordering > scv1.ordering and cv.ordering < scv2.ordering)"
  1408.                     ." or (scc1.book_id = scc2.book_id and scc1.book_id = vcc.book_id and scc1.ordering < scc2.ordering and vcc.ordering < scc1.ordering and vcc.ordering > scc2.ordering)"
  1409.                     ." or (scc1.book_id = scc2.book_id and scc1.book_id = vcc.book_id and scc1.ordering < scc2.ordering and vcc.ordering = scc1.ordering and cv.ordering > scv1.ordering)"
  1410.                     ." or (scc1.book_id = scc2.book_id and scc1.book_id = vcc.book_id and scc1.ordering < scc2.ordering and vcc.ordering = scc2.ordering and cv.ordering < scv2.ordering)"
  1411.                     .") and bs.id = sw.story_id and sw.work_id = t.work_id order by bs.id, lang_order) as t1"
  1412.                     ." order by ordering, name";
  1413.                     
  1414.              if($bCheck)
  1415.                   $sSql .= " limit 1";       
  1416.                     
  1417.      //    echo $sSql."<br>"; 
  1418.             $aRet $this->getNativeQueryResults($sSql);  
  1419.         }
  1420.          return $aRet;    
  1421.     }
  1422.     
  1423.     function getFirstExplainedVerse($aVerseInfo$request)
  1424.     {        
  1425.         if(empty($aVerseInfo))
  1426.             return array();
  1427.     
  1428.         $aRet = array();
  1429.         $sVerseIDs $aVerseInfo['VerseIDs'];
  1430.            
  1431.         if($sVerseIDs != '')
  1432.         {    
  1433.             $nUILanguageID $this->getUILanguageID($request);
  1434.             $nPreferredLanguageID $this->getUserPreferredLanguageID($request);
  1435.                         
  1436.             $nBookLanguageID $aVerseInfo['LanguageID'];
  1437.             
  1438.             $sLangOrder "case when t.language_id = " $nBookLanguageID " then 1";
  1439.             $sLangFilter " and t.language_id in (" $nBookLanguageID;
  1440.             
  1441.             $sEndStr "";
  1442.             if($nBookLanguageID != $nUILanguageID)
  1443.             {
  1444.                 $sLangOrder .= " else case when t.language_id = " $nUILanguageID " then 2";
  1445.                 $sEndStr .= " end ";
  1446.                 $sLangFilter .= "," $nUILanguageID;
  1447.             }
  1448.             
  1449.             if(!empty($nPreferredLanguageID) && $nBookLanguageID != $nPreferredLanguageID && $nUILanguageID != $nPreferredLanguageID)
  1450.             {
  1451.                 $sLangOrder .= ' else case when t.language_id = ' $nPreferredLanguageID ' then 3';    
  1452.                 $sEndStr .= " end ";
  1453.                 $sLangFilter .= "," $nPreferredLanguageID;
  1454.             }
  1455.                                     
  1456.             if($nBookLanguageID != $this->LANGUAGE_ID_ENGLISH && $nUILanguageID != $this->LANGUAGE_ID_ENGLISH && $nPreferredLanguageID != $this->LANGUAGE_ID_ENGLISH)
  1457.             {
  1458.                 $sLangOrder .= " else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 4";
  1459.                 $sEndStr .= " end ";
  1460.                 $sLangFilter .= "," $this->LANGUAGE_ID_ENGLISH;
  1461.             }
  1462.                                     
  1463.             $sLangOrder .= $sEndStr " end as lang_order";
  1464.             $sLangFilter .= ")";
  1465.         
  1466.             $sSql "SELECT v.id, cv.ordering as verse_order, scc.ordering as chapter_order, t.id as translation_id, scc.id as cchapter_id, v.chapter_id, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || bt.url || '_' || cb.url  || '_' || c.ordering  || '_' || v.indexdisplay as bible_spec, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, bt.url as bible_trans_url, cb.url as book_url, v.indexdisplay as verse_index, " $sLangOrder ", bt.language_id"
  1467.                     ." FROM (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_VERSE ") as bs, canonicalbibleverse cv, (select * from canonicalbibleverse_bibleverse where bibleverse_id in (" $sVerseIDs ")) as cvv, "
  1468.                     ." canonicalbiblechapter scc, expositionwork w, expositiontranslation t, expositiontranslationtext tt, story_work sw," 
  1469.                     ." biblechapter c, biblebook b, bibletranslation bt, canonicalbiblebook cb, bibleverse v" 
  1470.                     ." WHERE w.ispublic and t.ispublic"$sLangFilter
  1471.                     ." and v.id = cvv.bibleverse_id and cv.id = cvv.canonicalbibleverse_id"     
  1472.                     ." and bs.startverse_id = cv.id"                 
  1473.                     ." and cv.chapter_id = scc.id and v.verse_id is null"
  1474.                     ." and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"                   
  1475.                     ." and v.chapter_id = c.id and b.id = c.book_id and b.translation_id=bt.id and scc.book_id = cb.id and t.id = tt.translation_id and tt.text is not null and tt.text <> ''"
  1476.                     ." order by cv.ordering, lang_order, t.is_modern desc, w.ordering, t.islanguagedefault desc limit 1";
  1477.      //    echo $sSql."<br>";             
  1478.             $aTemp $this->getNativeQueryResults($sSql);
  1479.             if(count($aTemp) > 0
  1480.                 $aRet $aTemp[0];               
  1481.         }
  1482.          return $aRet;    
  1483.     }
  1484.     
  1485.     function getBibleTranslationByChapter($nChapterId$isCanonical)
  1486.     {                
  1487.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, cc.id as chapter_id, l.id as language_id"
  1488.                 ." FROM language l, bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb, canonicalbiblechapter cc";
  1489.          if($isCanonical)
  1490.               $sSql .= " where cc.id = " $nChapterId;
  1491.          else
  1492.               $sSql .= " where c.id = " $nChapterId;    
  1493.                     
  1494.          $sSql .= " and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled and t.language_id = l.id and cc.book_id = cb.id and cc.ordering = c.ordering limit 1";
  1495.   //   echo $sSql."<br>";   
  1496.            $aRet = array();
  1497.         $aTemp $this->getNativeQueryResults($sSql);
  1498.         if(count($aTemp) > 0
  1499.             $aRet $aTemp[0];        
  1500.                 
  1501.         return $aRet;   
  1502.     }
  1503.     
  1504.     function getBibleTranslationByUrl($translationUrl$nLanguageID=null)
  1505.     {                
  1506.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end as lang_ordering, case when t.languagedefault then 1 else 2 end as trans_ordering, l.id as language_id, t.abbreviation"
  1507.                 ." FROM language l, bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb"
  1508.                  ." WHERE t.url = '" trim(str_replace("'""''"$translationUrl)) . "'";                    
  1509.          $sSql .= " and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled and t.language_id = l.id";
  1510.          if($nLanguageID != null)
  1511.              $sSql .= " and l.id = " $nLanguageID;
  1512.          $sSql .= " order by lang_ordering, trans_ordering limit 1";
  1513.  //    echo $sSql."<br>";   
  1514.            $aRet = array();
  1515.         $aTemp $this->getNativeQueryResults($sSql);
  1516.         if(count($aTemp) > 0
  1517.             $aRet $aTemp[0];        
  1518.                 
  1519.         return $aRet;   
  1520.     }
  1521.     
  1522.     function getBibleTranslationByID($nTranslationID)
  1523.     {                
  1524.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end as lang_ordering, l.id as language_id"
  1525.                 ." FROM language l, bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb"
  1526.                  ." WHERE t.id = " $nTranslationID;                    
  1527.          $sSql .= " and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled and t.language_id = l.id limit 1";
  1528.   //   echo $sSql."<br>";   
  1529.            $aRet = array();
  1530.         $aTemp $this->getNativeQueryResults($sSql);
  1531.         if(count($aTemp) > 0
  1532.             $aRet $aTemp[0];        
  1533.                 
  1534.         return $aRet;   
  1535.     }
  1536.     
  1537.     function getDefaultBibleTranslationByLocale($locale)
  1538.     {                
  1539.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, case when l.shortcode = '" $locale "' then 1 else case when l.shortcode = 'en' then 2 else 3 end end as lang_ordering, l.id as language_id"
  1540.                 ." FROM language l, bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb"
  1541.                  ." WHERE c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled and t.language_id = l.id order by lang_ordering, languagedefault desc limit 1";
  1542.   //   echo $sSql."<br>";   
  1543.            $aRet = array();
  1544.         $aTemp $this->getNativeQueryResults($sSql);
  1545.         if(count($aTemp) > 0
  1546.             $aRet $aTemp[0];        
  1547.                 
  1548.         return $aRet;   
  1549.     }
  1550.     
  1551.     function getBibleTranslationByBookID($nBookID$nLanguageID)
  1552.     {                
  1553.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end as lang_ordering, case when t.languagedefault then 1 else 2 end as trans_ordering, l.id as language_id"
  1554.                 ." FROM language l, bibletranslation t, biblebook b, canonicalbiblebook cb"
  1555.                  ." WHERE b.id = ".  $nBookID;                    
  1556.          $sSql .= " and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled and t.language_id = l.id";
  1557.          if($nLanguageID != null)
  1558.              $sSql .= " and l.id = " $nLanguageID;
  1559.          $sSql .= " order by lang_ordering, trans_ordering limit 1";
  1560.   //   echo $sSql."<br>";   
  1561.            $aRet = array();
  1562.         $aTemp $this->getNativeQueryResults($sSql);
  1563.         if(count($aTemp) > 0
  1564.             $aRet $aTemp[0];        
  1565.                 
  1566.         return $aRet;   
  1567.     }
  1568.     
  1569.     function getFirstCanonicalBibleChapterID($bookUrl)
  1570.     {                
  1571.         $sSql "SELECT cc.id"
  1572.                 ." FROM canonicalbiblebook cb, canonicalbiblechapter cc"                
  1573.                 ." WHERE cb.url = '" trim(str_replace("'""''"$bookUrl)) . "'";
  1574.         $sSql .= " and cc.book_id = cb.id";  
  1575.         $sSql .= " order by cc.ordering limit 1";      
  1576.  //    echo $sSql;   
  1577.            $nRet null;
  1578.         $aTemp $this->getNativeQueryResults($sSql);
  1579.         if(count($aTemp) > 0
  1580.             $nRet $aTemp[0]['id'];        
  1581.                 
  1582.         return $nRet;   
  1583.     }
  1584.  
  1585.     function getAllBibleTranslationsByLanguage($canonical_book_id$chapter_order)
  1586.     {                
  1587.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name as name, t.url, bk.url as first_book_url, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as group_name, (case when language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) as group_order, (case when tr.translation_id is null then false else true end) as has_book, (case when tc.translation_id is null then false else true end) as has_chapter"
  1588.                 ." FROM language l, bibletranslation t"
  1589.                 ." join ("
  1590.                 ." select distinct on (t2.id) t2.id as translation_id, cb.url"
  1591.                 ." from bibletranslation t2, biblebook b, canonicalbiblebook cb where b.translation_id = t2.id and cb.id = b.canonicalization_id"
  1592.                 ." order by t2.id, b.ordering"
  1593.                 .") as bk on t.id = bk.translation_id"
  1594.                 ." left join (select translation_id from biblebook where canonicalization_id = " $canonical_book_id ") as tr on t.id = tr.translation_id"
  1595.                 ." left join (select distinct translation_id from biblebook b3, biblechapter c3 where b3.canonicalization_id = " $canonical_book_id " and c3.book_id = b3.id and c3.ordering = " $chapter_order ") as tc on t.id = tc.translation_id"
  1596.                 ." WHERE t.enabled and t.language_id = l.id";
  1597.                       
  1598.       $sSql .= " order by group_order, language_name, t.name";
  1599.  //   echo $sSql."<br>";   
  1600.            return $this->getNativeQueryResults($sSql);  
  1601.     }
  1602.     
  1603.     function getBibleTranslationsByLanguageForVerses($canonical_book_id$first_chapter_order$first_verse_display$last_chapter_order$last_verse_display$language_id=null)
  1604.     {                
  1605.         $sGroupOrder $this->getGroupOrderForBibleTranslation($language_id);
  1606.         
  1607.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name as name, t.url, bk.url as first_book_url, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as group_name, " $sGroupOrder " as group_order, true as has_book, true as has_chapter, l.righttoleft"
  1608.                 ." FROM language l, bibletranslation t"
  1609.                 ." join ("
  1610.                 ." select distinct on (t2.id) t2.id as translation_id, cb.url"
  1611.                 ." from bibletranslation t2, biblebook b, canonicalbiblebook cb where b.translation_id = t2.id and cb.id = b.canonicalization_id"                
  1612.                 ." order by t2.id, b.ordering"
  1613.                 .") as bk on t.id = bk.translation_id"
  1614.                 ." WHERE t.enabled and t.language_id = l.id"                
  1615.                 ." and t.id in (select distinct translation_id from biblebook b3, biblechapter c3, bibleverse v3 where b3.canonicalization_id = " $canonical_book_id " and c3.book_id = b3.id and c3.ordering = " $first_chapter_order " and v3.chapter_id = c3.id and v3.indexdisplay = '" $first_verse_display "')";
  1616.                 
  1617.       if($first_chapter_order != $last_chapter_order || $first_verse_display != $last_verse_display)
  1618.             $sSql .= " and t.id in (select distinct translation_id from biblebook b3, biblechapter c3, bibleverse v3 where b3.canonicalization_id = " $canonical_book_id " and c3.book_id = b3.id and c3.ordering = " $last_chapter_order " and v3.chapter_id = c3.id and v3.indexdisplay = '" $last_verse_display "')";
  1619.                       
  1620.       $sSql .= " order by group_order, language_name, t.name";
  1621.  //    echo $sSql."<br>";   
  1622.            return $this->getNativeQueryResults($sSql);  
  1623.     }
  1624.     
  1625.     function getBibleTranslation($nTranslationID$bookID)
  1626.     {                
  1627.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, l.id as language_id"
  1628.                 ." FROM language l, bibletranslation t, biblebook b, canonicalbiblebook cb"
  1629.                  ." WHERE t.id = " $nTranslationID " and cb.id = " $bookID;                    
  1630.          $sSql .= " and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled and t.language_id = l.id limit 1";
  1631.    //  echo $sSql."<br>";   
  1632.            $aRet = array();
  1633.         $aTemp $this->getNativeQueryResults($sSql);
  1634.         if(count($aTemp) > 0
  1635.             $aRet $aTemp[0];        
  1636.                 
  1637.         return $aRet;   
  1638.     }
  1639.     
  1640.     function getBibleTranslationByLanguage($nLanguageID)
  1641.     {                
  1642.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end as lang_ordering, case when t.languagedefault then 1 else 2 end as trans_ordering, l.id as language_id"
  1643.                 ." FROM language l, bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb"
  1644.                  ." WHERE l.id = " $nLanguageID " and t.language_id = l.id";                    
  1645.          $sSql .= " and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled ";         
  1646.          $sSql .= " order by lang_ordering, trans_ordering limit 1";
  1647.  //    echo $sSql."<br>";   
  1648.            $aRet = array();
  1649.         $aTemp $this->getNativeQueryResults($sSql);
  1650.         if(count($aTemp) > 0
  1651.             $aRet $aTemp[0];        
  1652.                 
  1653.         return $aRet;    
  1654.     }
  1655.     
  1656.     function getStoriesForTranslation($translation_id$story_num)
  1657.     {               
  1658.         $sSql "SELECT distinct bs.id, bs.url, bs.name, si.file as image_file, cb1.name as book_name, cc1.ordering as start_chapter_order, cv1.ordering as start_verse_order, cc2.ordering as end_chapter_order, cv2.ordering as end_verse_order, ci1.first_order as start_chapter_min_order, ci1.last_order as start_chapter_max_order, ci2.first_order as end_chapter_min_order, ci2.last_order as end_chapter_max_order, t.url as translation_url"
  1659.                 ." FROM story_work sw, expositiontranslation t, expositionwork w, canonicalbibleverse cv1, canonicalbiblechapter cc1, canonicalbiblebook cb1, canonicalbibleverse cv2, canonicalbiblechapter cc2, " 
  1660.                 ." (select id, min(ordering) as first_order, max(ordering) as last_order from canonicalbiblechapter group by id) as ci1, "
  1661.                 ." (select id, min(ordering) as first_order, max(ordering) as last_order from canonicalbiblechapter group by id) as ci2, (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE ") as bs"
  1662.                 ." left join (select distinct on (si1.story_id) si1.story_id, i.file from storyillustration si1, image i where i.id = si1.image_id and i.mediatype_id = " $this->MEDIA_TYPE_ID_IMAGE ") as si on bs.id = si.story_id"
  1663.                 ." WHERE cc1.book_id in (select canonicalization_id from biblebook where translation_id = " $translation_id ")"
  1664.                 ." and w.ispublic and t.ispublic and sw.work_id = w.id"
  1665.                 ." and cv1.chapter_id = cc1.id and cv1.id = bs.startverse_id"
  1666.                 ." and bs.id = sw.story_id and t.work_id = sw.work_id"                
  1667.                 ." and cb1.id = cc1.book_id"                
  1668.                 ." and cv2.chapter_id = cc2.id and cv2.id = bs.endverse_id"
  1669.                 ." and ci1.id = cc1.id"
  1670.                 ." and ci2.id = cc2.id";
  1671.                 
  1672.                 if($story_num != null and $story_num 0)
  1673.                     $sSql .= " limit " $story_num;
  1674.  //    echo $sSql."<br>"; 
  1675.         $aRet $this->getNativeQueryResults($sSql);  
  1676.            $nLen count($aRet);           
  1677.            for($i=0;$i<$nLen;$i++)
  1678.            {                                  
  1679.             $startChapterNum $aRet[$i]["start_chapter_order"];
  1680.             $endChapterNum $aRet[$i]["end_chapter_order"];
  1681.             $startVerseNum $aRet[$i]["start_verse_order"];
  1682.             $endVerseNum $aRet[$i]["end_verse_order"];
  1683.             $bookName $aRet[$i]["book_name"];
  1684.             if($bookName == 'Psalms') {
  1685.                 $bookName 'Psalm';
  1686.             } else {
  1687.                 $bookName str_replace('_'' '$bookName);
  1688.             }
  1689.     
  1690.             $fullChapter = ($startVerseNum == $aRet[$i]["start_chapter_min_order"] && $endVerseNum == $aRet[$i]["end_chapter_max_order"]);
  1691.             if($fullChapter) {
  1692.                 if($startChapterNum == $endChapterNum) {
  1693.                     $bookName .= ' '.$startChapterNum;
  1694.                 } else {
  1695.                     $bookName .= ' '.$startChapterNum.'-'.$endChapterNum;
  1696.                 }
  1697.             } else {
  1698.                 if($startChapterNum != $endChapterNum) {
  1699.                     $bookName .= ' '.$startChapterNum.':'.$startVerseNum.'-'.$endChapterNum.':'.$endVerseNum;
  1700.                 } elseif($startVerseNum != $endVerseNum) {
  1701.                     $bookName .= ' '.$startChapterNum.':'.$startVerseNum.'-'.$endVerseNum;
  1702.                 } else {
  1703.                     $bookName .= ' '.$startChapterNum.':'.$startVerseNum;
  1704.                 }
  1705.             }
  1706.             
  1707.             $aRet[$i]["verse_range_text"] = $bookName;
  1708.            } 
  1709.        
  1710.          return $aRet;    
  1711.     }
  1712.     
  1713.     function getBibleTranslationByCanonBookID($nCBookID$nLanguageID)
  1714.     {                
  1715.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name, t.url, l.righttoleft, b.id as book_id, b.name as book_name, cb.url as canonical_book_url, case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end as lang_ordering, case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end as lang_ordering, case when t.languagedefault then 1 else 2 end as trans_ordering, l.id as language_id"
  1716.                 ." FROM language l, bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb"
  1717.                  ." WHERE cb.id = ".  $nCBookID;                    
  1718.          $sSql .= " and b.canonicalization_id = cb.id and c.book_id = b.id and b.translation_id = t.id and t.enabled and t.language_id = l.id";
  1719.          if($nLanguageID != null)
  1720.              $sSql .= " and l.id = " $nLanguageID;
  1721.          $sSql .= " order by lang_ordering, trans_ordering limit 1";
  1722. //     echo $sSql."<br>";   
  1723.            $aRet = array();
  1724.         $aTemp $this->getNativeQueryResults($sSql);
  1725.         if(count($aTemp) > 0
  1726.             $aRet $aTemp[0];        
  1727.                 
  1728.         return $aRet;   
  1729.     }
  1730.     
  1731.     function getLanguageByBibliographicCode($language_code)
  1732.     {                
  1733.         $sSql "SELECT id, (case when nativename is not null and nativename <> '' then nativename else name end) as name FROM language" 
  1734.                 ." WHERE bibliographiccode = '" trim(str_replace("'""''"$language_code)) . "' limit 1";
  1735.   //   echo $sSql."<br>";   
  1736.            $aRet = array();
  1737.         $aTemp $this->getNativeQueryResults($sSql);
  1738.         if(count($aTemp) > 0
  1739.             $aRet $aTemp[0];        
  1740.                 
  1741.         return $aRet;   
  1742.     }
  1743.     
  1744.     function getFirstBibleChapterOrder($translation_url$book_url)
  1745.     {                
  1746.         $sSql "SELECT min(c.ordering) as first_chapter_order"
  1747.                 ." FROM bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb" 
  1748.                 ." WHERE t.url = '" trim(str_replace("'""''"$translation_url)) . "' and t.enabled and b.translation_id = t.id and cb.url = '" trim(str_replace("'""''"$book_url)) . "' "
  1749.                 ." and c.book_id = b.id and b.canonicalization_id = cb.id";
  1750.   //   echo $sSql."<br>";   
  1751.            $nRet null;
  1752.         $aTemp $this->getNativeQueryResults($sSql);
  1753.         if(count($aTemp) > 0
  1754.             $nRet current($aTemp[0]);        
  1755.                 
  1756.         return $nRet;   
  1757.     }
  1758.     
  1759.     function getLanguageByID($language_id)
  1760.     {                
  1761.         $sSql "SELECT id, case when searchlibrary is null then 'simple' else searchlibrary end as searchlibrary FROM language" 
  1762.                 ." WHERE id = " $language_id;
  1763.  //    echo $sSql."<br>";   
  1764.            $aRet = array();
  1765.         $aTemp $this->getNativeQueryResults($sSql);
  1766.         if(count($aTemp) > 0
  1767.             $aRet $aTemp[0];        
  1768.                 
  1769.         return $aRet;   
  1770.     }
  1771.     
  1772.     function getLanguageByShortCode($language_code)
  1773.     {                
  1774.         $sSql "SELECT id, case when searchlibrary is null then 'simple' else searchlibrary end as searchlibrary FROM language" 
  1775.                 ." WHERE shortcode = '" trim(str_replace("'""''"$language_code)) . "' limit 1";
  1776.   //   echo $sSql."<br>";   
  1777.            $aRet = array();
  1778.         $aTemp $this->getNativeQueryResults($sSql);
  1779.         if(count($aTemp) > 0
  1780.             $aRet $aTemp[0];        
  1781.                 
  1782.         return $aRet;   
  1783.     } 
  1784.     
  1785.     function getLanguageIDByShortCode($language_code)
  1786.     {                
  1787.         $sSql "SELECT id FROM language" 
  1788.                 ." WHERE shortcode = '" trim(str_replace("'""''"$language_code)) . "' limit 1";
  1789.   //   echo $sSql."<br>";   
  1790.            $nRet null;
  1791.         $aTemp $this->getNativeQueryResults($sSql);
  1792.         if(count($aTemp) > 0
  1793.             $nRet $aTemp[0]['id'];        
  1794.                 
  1795.         return $nRet;   
  1796.     }
  1797.     
  1798.      // $book should be biblebook, not canonical book
  1799.     function getChapterExplanations($book$work_translation$request)
  1800.     {    
  1801.         $sSql '';    
  1802.         $nCurrTranslationID $work_translation->getId();
  1803.     //    $nLanguageID = $work_translation->getLanguage()->getId();
  1804.         $nLanguageID $book->getTranslation()->getLanguage()->getId();
  1805.         $nUILanguageID $this->getUILanguageID($request);
  1806.         $nPreferredLanguageID $this->getUserPreferredLanguageID($request);
  1807.             
  1808.         $nCountOtherCase 0;
  1809.         $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  1810.         if($nLanguageID != $nUILanguageID)
  1811.         {
  1812.             $sLangStr .= ' case when t.language_id = ' $nUILanguageID ' then 2 else';
  1813.             $nCountOtherCase++;
  1814.         }    
  1815.             
  1816.         if(!empty($nPreferredLanguageID) && $nLanguageID != $nPreferredLanguageID && $nUILanguageID != $nPreferredLanguageID)
  1817.         {
  1818.             $sLangStr .= ' case when t.language_id = ' $nPreferredLanguageID ' then 3 else';    
  1819.             $nCountOtherCase++;
  1820.         }    
  1821.         
  1822.         if($nLanguageID != $this->LANGUAGE_ID_ENGLISH && $nUILanguageID != $this->LANGUAGE_ID_ENGLISH && $nPreferredLanguageID != $this->LANGUAGE_ID_ENGLISH)
  1823.         {
  1824.             $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 4 else';
  1825.             $nCountOtherCase++;
  1826.         }    
  1827.             
  1828.         $sLangStr .= ' 5 end';
  1829.         
  1830.         for($i=0;$i<$nCountOtherCase;$i++)
  1831.             $sLangStr .= ' end';
  1832.             
  1833.         $sLangStr .= ' as lang_order';
  1834.         
  1835.         if($book != null)
  1836.         {
  1837.             $sSql "select distinct on (chapter_order) * from (SELECT distinct t.id as translation_id, bs.name as explanationtitle, bs.chapter_id as cchapter_id, bible.chapter_id, cbc.ordering as chapter_order, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || '" $book->getTranslation()->getUrl() . "' || '_' || '" $book->getCanonicalization()->getUrl() . "' || '_' || bible.chapter_order as bible_spec, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, " $sLangStr ", case when t.id = " $nCurrTranslationID " then 1 else case when t.islanguagedefault then 2 else 3 end end as trans_order, t.is_modern, w.id as work_id, bs.id as story_id"
  1838.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, canonicalbiblechapter cbc, biblestory bs"                
  1839.                 ." left join (SELECT distinct bc.id as chapter_id, bc.ordering as chapter_order, cbc.id as cchapter_id FROM bibleverse bv, biblechapter bc, canonicalbibleverse_bibleverse cbv_bv, canonicalbiblechapter cbc, canonicalbibleverse cbv where bc.book_id = " $book->getId() . " and bv.chapter_id = bc.id and bv.id = cbv_bv.bibleverse_id and cbv.id = cbv_bv.canonicalbibleverse_id and cbv.chapter_id = cbc.id) as bible on bs.chapter_id = bible.cchapter_id"
  1840.                 ." WHERE bs.chapter_id in (select id from canonicalbiblechapter where book_id in (select book_id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $work_translation->getWork()->getId() . " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id)) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  1841.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic order by cbc.ordering, lang_order, t.is_modern desc, trans_order) as t";
  1842.         }
  1843.         else
  1844.         {
  1845.             $sSql "select distinct on (chapter_order,work_id) * from (SELECT t.id as translation_id, bs.name as explanationtitle, bs.chapter_id as cchapter_id, null as chapter_id, cbc.ordering as chapter_order, t.url as translation_url, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, " $sLangStr ", case when t.id = " $nCurrTranslationID " then 1 else case when t.islanguagedefault then 2 else 3 end end as trans_order, t.is_modern, w.id as work_id, bs.id as story_id"
  1846.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs, canonicalbiblechapter cbc"
  1847.                 ." WHERE bs.chapter_id in (select id from canonicalbiblechapter where book_id in (select book_id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $work_translation->getWork()->getId() . " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id)) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  1848.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic) as t order by chapter_order, lang_order, is_modern desc, trans_order desc";
  1849.         }  
  1850.     //    echo $sSql."<br>";
  1851.  
  1852.          $aRet = array();
  1853.          $aTemp $this->getNativeQueryResults($sSql);
  1854.          if($book != null && !empty($aTemp))
  1855.         {
  1856.             foreach($aTemp as $t)
  1857.                {      
  1858.                    $aRet[$t["chapter_id"]] = $t;
  1859.                } 
  1860.         }
  1861.         else
  1862.             $aRet $aTemp;
  1863.                     
  1864.         return $aRet
  1865.     }  
  1866.     
  1867.     // $book should be biblebook, not canonical book
  1868.     function getChapterExplanationsForCombo($book$work_translation)
  1869.     {    
  1870.         $sSql '';    
  1871.         $nCurrTranslationID $work_translation->getId();
  1872.         //$nLanguageID = $work_translation->getLanguage()->getId();
  1873.         $nLanguageID $book->getTranslation()->getLanguage()->getId();
  1874.         $nCurrWorkID $work_translation->getWork()->getId();
  1875.         if($book != null)
  1876.         {            
  1877.             $sSql "SELECT distinct t.id as translation_id, t.translatedtitle as explanationtitle, bs.chapter_id as cchapter_id, bible.chapter_id, cbc.ordering as chapter_order, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || '" $book->getTranslation()->getUrl() . "' || '_' || '" $book->getCanonicalization()->getUrl() . "' || '_' || bible.chapter_order as bible_spec, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, case when t.language_id = " $nLanguageID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 end end as lang_order, case when t.id = " $nCurrTranslationID " then 1 else case when t.islanguagedefault then 2 else 3 end end as trans_order, w.id as work_id, t.is_modern, bs.id as story_id, t.language_id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name "
  1878.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, canonicalbiblechapter cbc, language l, biblestory bs"                
  1879.                 ." left join (SELECT distinct bc.id as chapter_id, bc.ordering as chapter_order, cbc.id as cchapter_id FROM bibleverse bv, biblechapter bc, canonicalbibleverse_bibleverse cbv_bv, canonicalbiblechapter cbc, canonicalbibleverse cbv where bc.book_id = " $book->getId() . " and bv.chapter_id = bc.id and bv.id = cbv_bv.bibleverse_id and cbv.id = cbv_bv.canonicalbibleverse_id and cbv.chapter_id = cbc.id) as bible on bs.chapter_id = bible.cchapter_id"
  1880.                 ." WHERE bs.chapter_id in (select cbc2.id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $nCurrWorkID " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and t.language_id = l.id"
  1881.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic order by lang_order, t.is_modern desc, trans_order";
  1882.         }
  1883.         else
  1884.         {
  1885.             $sSql "SELECT t.id as translation_id, w.title as explanationtitle, bs.chapter_id as cchapter_id, null as chapter_id, cbc.ordering as chapter_order, t.url as translation_url, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, case when t.language_id = " $nLanguageID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 end end as lang_order, case when t.id = " $nCurrTranslationID " then 1 else case when t.islanguagedefault then 2 else 3 end end as trans_order, w.id as work_id, t.is_modern, bs.id as story_id, t.language_id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name"
  1886.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs, canonicalbiblechapter cbc, language l"
  1887.                 ." WHERE bs.chapter_id in (select cbc2.id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $nCurrWorkID " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and t.language_id = l.id"
  1888.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic order by lang_order, t.is_modern desc, trans_order";
  1889.         }  
  1890.   //      echo $sSql."<br>";
  1891.  
  1892. /*         $aRet = array();
  1893.          $aTemp = $this->getNativeQueryResults($sSql);
  1894.          if($book != null && !empty($aTemp))
  1895.         {
  1896.             foreach($aTemp as $t)
  1897.                {      
  1898.                    $aRet[$t["chapter_id"]] = $t;
  1899.                } 
  1900.         }
  1901.         else
  1902.             $aRet = $aTemp;
  1903.                     
  1904.         return $aRet; */
  1905.         
  1906.         return $this->getNativeQueryResults($sSql);
  1907.     }  
  1908.         
  1909.     // $chapter_id: verse's chapter id
  1910.     function getVerseExplanations($chapter_id$nLanguageID$request)
  1911.     {    
  1912.         $nUILanguageID $this->getUILanguageID($request);
  1913.         $nPreferredLanguageID $this->getUserPreferredLanguageID($request);
  1914.             
  1915.         $nCountOtherCase 0;
  1916.         $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  1917.         if($nLanguageID != $nUILanguageID)
  1918.         {
  1919.             $sLangStr .= ' case when t.language_id = ' $nUILanguageID ' then 2 else';
  1920.             $nCountOtherCase++;
  1921.         }    
  1922.             
  1923.         if(!empty($nPreferredLanguageID) && $nLanguageID != $nPreferredLanguageID && $nUILanguageID != $nPreferredLanguageID)
  1924.         {
  1925.             $sLangStr .= ' case when t.language_id = ' $nPreferredLanguageID ' then 3 else';    
  1926.             $nCountOtherCase++;
  1927.         }    
  1928.         
  1929.         if($nLanguageID != $this->LANGUAGE_ID_ENGLISH && $nUILanguageID != $this->LANGUAGE_ID_ENGLISH && $nPreferredLanguageID != $this->LANGUAGE_ID_ENGLISH)
  1930.         {
  1931.             $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 4 else';
  1932.             $nCountOtherCase++;
  1933.         }    
  1934.             
  1935.         $sLangStr .= ' 5 end';
  1936.         
  1937.         for($i=0;$i<$nCountOtherCase;$i++)
  1938.             $sLangStr .= ' end';
  1939.             
  1940.         $sLangStr .= ' as lang_order';
  1941.             
  1942.         $sSql "select distinct on (verse_order) * from (SELECT t.id as translation_id, bs.name as explanationtitle, v.id as verse_id, t.url as translation_url, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || bt.url || '_' || cb.url  || '_' || c.ordering  || '_' || v.indexdisplay as bible_spec, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, sw.story_id, cv.ordering as verse_order, " $sLangStr
  1943.        .", t.work_id FROM (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_VERSE ") as bs, canonicalbibleverse cv, bibleverse v, canonicalbibleverse_bibleverse cvv,"
  1944.                     ." canonicalbiblechapter scc, expositionwork w, expositiontranslation t, story_work sw," 
  1945.                     ." biblechapter c, biblebook b, bibletranslation bt, canonicalbiblebook cb" 
  1946.                     ." WHERE v.chapter_id = " $chapter_id
  1947.                     ." and v.id = cvv.bibleverse_id and cv.id = cvv.canonicalbibleverse_id"     
  1948.                     ." and bs.startverse_id = cv.id"                 
  1949.                     ." and cv.chapter_id = scc.id"
  1950.                     ." and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  1951.                     ." and w.ispublic and t.ispublic"
  1952.                     ." and v.chapter_id = c.id and b.id = c.book_id and b.translation_id=bt.id and scc.book_id = cb.id and v.verse_id is null"
  1953.                     ." order by cv.ordering, lang_order) as t order by verse_order";          
  1954.   //    echo $sSql."<br>";                
  1955.         $aRet = array();
  1956.          $aTemp $this->getNativeQueryResults($sSql);
  1957.          if(!empty($aTemp))
  1958.         {                      
  1959.                foreach($aTemp as $t)
  1960.                {      
  1961.                    $aRet[$t["verse_id"]] = $t;
  1962.                } 
  1963.         }
  1964.         else
  1965.             $aRet $aTemp;
  1966.                     
  1967.         return $aRet
  1968.     }  
  1969.         
  1970.     function getFeaturedStoryList($locale$vLimit$vUseDefaultLang=false)
  1971.     {
  1972.         if($vUseDefaultLang)
  1973.             $nLanguageID $this->LANGUAGE_ID_ENGLISH;
  1974.         else
  1975.             $nLanguageID $this->getLanguageIDByShortCode($locale);
  1976.         $sSql "select * from (SELECT distinct on (t.id) t.translatedtitle AS title, t.description, t.url, bsw.story_id, bsw.story_url, t.url as translation_url, wo.feature_ordering, ";
  1977.         $sSql .= "case when fi.image_file is null then case when fi2.image_file is null then ti.image_file else fi2.image_file end else fi.image_file end as image_file, case when fi.image_file is null then ti.image_title else fi.image_title end as image_title";
  1978.         $sSql .= " FROM expositionwork w, expositiontranslation t";
  1979.         
  1980.         // featured image from the current translation
  1981.         $sSql .= " left join (select distinct on (t1.id) t1.id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on t.id = fi.id";
  1982.         
  1983.         // featured image from the translation with image 
  1984.         $sSql .= " left join (select distinct on (t1.work_id) t1.work_id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id order by t1.work_id, case when t1.language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) fi2 on t.work_id = fi2.work_id";
  1985.         
  1986.         // textunit image
  1987.         $sSql .= " left join (select distinct on (tt1.translation_id) tt1.translation_id, i.file as image_file, i.title as image_title from textunit_image ti, image i, expositiontranslationtext tt1 where ti.textunit_id = tt1.placement_id and ti.image_id = i.id and i.mediatype_id = 1) ti on t.id = ti.translation_id";        
  1988.                 
  1989.         $sSql .= " join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") as wo on t.work_id = wo.work_id"
  1990.                 ." join (select bs.id, bs.url as story_url, sw.work_id, sw.story_id from story_work sw, (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE ") as bs where bs.id = sw.story_id) bsw on t.work_id = bsw.work_id"
  1991.                 ." WHERE t.language_id = " $nLanguageID " AND t.ispublic AND w.ispublic and t.work_id=w.id"
  1992.                 ." and story_url is not null"
  1993.                 
  1994.                 $sSql .= ") as t1"
  1995.                 ." ORDER BY t1.feature_ordering";
  1996.                 
  1997.                 if($vLimit != null && $vLimit 0)
  1998.                  $sSql .= " limit " $vLimit;               
  1999.                
  2000.  // echo $sSql."<br>";              
  2001.         return $this->getNativeQueryResults($sSql);
  2002.     }    
  2003.     
  2004.     function getFeaturedListByCategory($vCategoryId$locale$vLimit$vUseDefaultLang=false)
  2005.     {
  2006.         if($vUseDefaultLang)
  2007.             $nLanguageID $this->LANGUAGE_ID_ENGLISH;
  2008.         else
  2009.             $nLanguageID $this->getLanguageIDByShortCode($locale);
  2010.         $bConcept = ($vCategoryId == $this->CATEGORY_ID_CONCEPT);
  2011.         $sSql "select * from (SELECT distinct on (t.id) t.translatedtitle AS title, t.description, t.url, wo.feature_ordering, ";
  2012.         
  2013.         if($bConcept)
  2014.         {
  2015.             $sSql .= "case when fi.image_file is not null then fi.image_file else case when fi2.image_file is not null then fi2.image_file else case when ci.image_file is not null then ci.image_file else ti.image_file end end end as image_file, case when ci.image_file is not null then ci.image_title else case when fi.image_file is not null then fi.image_title else case when fi2.image_file is not null then fi2.image_title else ti.image_title end end end  as image_title";
  2016.         }
  2017.         else
  2018.         {
  2019.             $sSql .= "case when fi.image_file is not null then fi.image_file else case when fi2.image_file is not null then fi2.image_file else ti.image_file end end as image_file, case when fi.image_file is not null then fi.image_title else case when fi2.image_file is not null then fi2.image_title else ti.image_title end end as image_title";
  2020.         }
  2021.         
  2022.         $sSql .= " FROM expositionwork w, expositiontranslation t ";
  2023.        
  2024.        // featured image from the current translation
  2025.         $sSql .= " left join (select distinct on (t1.id) t1.id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on t.id = fi.id";
  2026.         
  2027.         // featured image from the translation with image 
  2028.         $sSql .= " left join (select distinct on (t1.work_id) t1.work_id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id order by t1.work_id, case when t1.language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) fi2 on t.work_id = fi2.work_id";
  2029.         
  2030.         // textunit image
  2031.         $sSql .= " left join (select distinct on (tt1.translation_id) tt1.translation_id, i.file as image_file, i.title as image_title from textunit_image ti, image i, expositiontranslationtext tt1 where ti.textunit_id = tt1.placement_id and ti.image_id = i.id and i.mediatype_id = 1) ti on t.id = ti.translation_id";
  2032.                     
  2033.        if($bConcept)
  2034.         {
  2035.             $sSql .= " left join (select distinct on (cl.work_id) cl.work_id as id, i.file as image_file, i.title as image_title from image i, conceptillustration ci1, concept_work cl where cl.concept_id = ci1.concept_id and ci1.image_id = i.id) ci on t.work_id = ci.id";
  2036.         }
  2037.           
  2038.        $sSql .= " join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") as wo on t.work_id = wo.work_id"         
  2039.                 ." WHERE (t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $vCategoryId ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $vCategoryId ")) and t.language_id = " $nLanguageID " AND t.ispublic and w.ispublic and t.work_id=w.id";   
  2040.                 
  2041.                 $sSql .= ") as t1 ORDER BY t1.feature_ordering";
  2042.                 
  2043.                 if($vLimit != null && $vLimit 0)
  2044.                  $sSql .= " limit " $vLimit;
  2045.                               
  2046. //  echo $sSql."<br>";           
  2047.         return $this->getNativeQueryResults($sSql);
  2048.     }  
  2049.     
  2050.     function getConsiderList($locale$sSearchText=null)
  2051.     {
  2052.         $sSql "SELECT t.translatedtitle AS title, t.url as translation_url, d.url as division_url, '" $this->MULTI_URL_INDICATOR_EXPLANATION "_' || t.url as ref_column_spec, w.id as work_id, t.id as translation_id"
  2053.                 ." FROM expositionwork w, expositiontranslation t, (select distinct on (work_id) work_id, url, min(ordering) as ordering from expositiondivision group by work_id, url) as d"
  2054.                 ." WHERE t.work_id=w.id and w.id in (select work_id from work_category where category_id = " $this->CATEGORY_ID_SPIRITUAL_TOPIC ")"
  2055.                     ." and d.work_id = w.id AND w.ispublic AND t.ispublic"
  2056.                     ." AND w.swedenborgtype IS NULL"
  2057.                     ." AND t.translatedtitle IS NOT NULL and t.id in (";
  2058.           
  2059.           $sSql .= "SELECT distinct on (w.id) t.id"
  2060.                 ." FROM expositionwork w, expositiontranslation t, language l WHERE ";      
  2061.                 
  2062.           $sSql .= " t.work_id=w.id and t.language_id = l.id order by w.id, (case when l.shortcode = '" $locale "' then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end), t.islanguagedefault desc)"
  2063.                     ." AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  2064.                     
  2065.           if(!empty($sSearchText))
  2066.               $sSql .= " and lower(t.translatedtitle) like '%" str_replace("'""''"strtolower($sSearchText)) . "%'";
  2067.                     
  2068.           $sSql .= " order by w.ordering, t.translatedtitle";
  2069.  //   echo $sSql."<br>";   
  2070.         return $this->getNativeQueryResults($sSql);
  2071.     }  
  2072.     
  2073.     function getBibleStudyList($locale)
  2074.     {
  2075.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id, t.translatedtitle AS title, t.url as translation_url, d.url as division_url"
  2076.                 .", (case when b.datecreated is null then null else to_date(b.datecreated, 'MM/DD/YYYY') end) as datecreated, '" $this->MULTI_URL_INDICATOR_EXPLANATION "_' || t.url as ref_column_spec, t.id as translation_id"
  2077.                 ." FROM expositionwork w, expositiontranslation t, expositiondivision d, bibliographicdata b, translation_bibliographicdata tb, language l"
  2078.                 ." WHERE t.work_id=w.id and w.id in (select work_id from work_category where category_id = " $this->CATEGORY_ID_BIBLE_STUDY ")"
  2079.                     ." and d.work_id = w.id AND w.ispublic AND t.ispublic"
  2080.                     ." AND w.swedenborgtype IS NULL"
  2081.                     ." AND t.translatedtitle IS NOT NULL"
  2082.                     ." AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT
  2083.                 ." and t.id = tb.translation_id and t.language_id = l.id and b.id = tb.bibliographicdata_id ORDER BY  w.id, (case when l.shortcode = '" $locale "' then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end), t.islanguagedefault desc) as t order by datecreated";
  2084.  // echo $sSql."<br>";              
  2085.         return $this->getNativeQueryResults($sSql);        
  2086.     }  
  2087.     
  2088.     function getOtherBibleRefPassage($aVerseInfo$category_id)
  2089.     {                
  2090.         $canon = array();
  2091.         $nulls = array();
  2092.         $verseLanguage null;
  2093.         $sVerseIDs $aVerseInfo['CVerseIDs'];
  2094.         $verseLanguage $aVerseInfo['LanguageID'];
  2095.  /*       foreach($verses as $verse) {
  2096.             if($verse === null) {
  2097.                 continue;
  2098.             }
  2099.             foreach($verse->getCanonicalization() as $canonicalVerse) {
  2100.                 if($canonicalVerse != null) 
  2101.                 {                
  2102.                     if($sVerseIDs != '')
  2103.                         $sVerseIDs .= ',';
  2104.                   
  2105.                     $sVerseIDs .= $canonicalVerse->getId();
  2106.                 }
  2107.             }
  2108.             
  2109.             if($verseLanguage == null)
  2110.                 $verseLanguage = $verse->getLanguage()->getId();
  2111.         } */
  2112.         
  2113.         if($verseLanguage == '')
  2114.             $verseLanguage $this->LANGUAGE_ID_ENGLISH;
  2115.         
  2116.         if($sVerseIDs == '') {
  2117.             return null;
  2118.         } else {                    
  2119.             return $this->getOtherBibleRefPassageInfo($verseLanguage$sVerseIDs$category_id);
  2120.         }
  2121.     } 
  2122.     
  2123.     function getOtherBibleRefPassageInfo($language_id$sVerseIDs$category_id)
  2124.     {            
  2125.         if($sVerseIDs == ''
  2126.             return array();
  2127.             
  2128.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English    
  2129.                     
  2130.         $sFilter " p.id in (SELECT DISTINCT passage_id FROM verse_passage"
  2131.                 ." WHERE verse_id in (" $sVerseIDs "))";
  2132.         
  2133.         $sFilter .= " and w.swedenborgtype is null and w.id in (select work_id from work_category where category_id = " $category_id ")";
  2134.                 
  2135.         $sSql "select * from (SELECT distinct on (p.id) p.id, w.swedenborgtype, t.translatedtitle AS title, p.swedenborgsection as num, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as ref_column_spec, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering, case when t.language_id = " $language_id " then 1 else 2 end as lang_order"
  2136.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  2137.                 ." WHERE " $sFilter;          
  2138.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (";
  2139.           
  2140.           $sSql .= "SELECT distinct on (w.id) t.id"
  2141.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  2142.                 ." WHERE " $sFilter;          
  2143.                 
  2144.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and in ( ".$language_id"," $nDefaultLanguageID ") and t.ispublic and w.ispublic";
  2145.           $sSql .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  2146.           $sSql .= " order by w.id, t.islanguagedefault desc) order by p.id, lang_order"
  2147.           
  2148. /*          if($language_id != $nDefaultLanguageID)
  2149.           {
  2150.                 $sSql .= " union SELECT distinct on (p.id) p.id, w.swedenborgtype, t.translatedtitle AS title, p.swedenborgsection as num, (case when w.swedenborgtype is not null then '" . $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK . "' else '" . $this->MULTI_URL_INDICATOR_EXPLANATION . "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as ref_column_spec, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering"
  2151.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  2152.                 ." WHERE " . $sFilter;          
  2153.                 $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (";
  2154.           
  2155.           $sSql .= "SELECT distinct on (w.id) t.id"
  2156.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  2157.                 ." WHERE " . $sFilter;          
  2158.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id = ".$nDefaultLanguageID. " and t.ispublic and w.ispublic";
  2159.           $sSql .= " AND t.type_id = " . $this->TRANSLATION_TYPE_ID_TEXT;
  2160.           $sSql .= " order by w.id, t.islanguagedefault desc)"; 
  2161.                 
  2162.                 $sSql .= " and p.id not in (";
  2163.                 
  2164.                 $sSql .= "SELECT distinct p.id"
  2165.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  2166.                 ." WHERE " . $sFilter;          
  2167.                 $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (";
  2168.           
  2169.           $sSql .= "SELECT distinct on (w.id) t.id"
  2170.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  2171.                 ." WHERE " . $sFilter;          
  2172.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id = ".$language_id. " and t.ispublic and w.ispublic";
  2173.           $sSql .= " AND t.type_id = " . $this->TRANSLATION_TYPE_ID_TEXT;
  2174.           $sSql .= " order by w.id, t.islanguagedefault desc)"; 
  2175.                 $sSql .= ")";
  2176.           } */
  2177.                         
  2178.           $sSql .= ") as t2 order by work_order, title, ordering";
  2179.  //    echo $sSql."<br>";   
  2180.            return $this->getNativeQueryResults($sSql);  
  2181.     }
  2182.     
  2183.     function getBibleChapterID($sTranslationUrl$sBookUrl$nChapterNum=null)
  2184.     {                
  2185.         $sSql "SELECT c.id"
  2186.                 ." FROM biblebook b, biblechapter c, bibletranslation t, canonicalbiblebook cb"                
  2187.                 ." WHERE t.url = '" trim(str_replace("'""''"$sTranslationUrl)) . "'"
  2188.                 ." and cb.url = '" trim(str_replace("'""''"$sBookUrl)) . "'";
  2189.                 
  2190.         if($nChapterNum != null
  2191.            $sSql .= " and c.ordering = " $nChapterNum;
  2192.            
  2193.         $sSql .= " and b.canonicalization_id = cb.id and b.translation_id = t.id and c.book_id = b.id limit 1";      
  2194.  //    echo $sSql."<br>";   
  2195.            $nRet null;
  2196.         $aTemp $this->getNativeQueryResults($sSql);
  2197.         if(count($aTemp) > 0
  2198.             $nRet $aTemp[0]['id'];        
  2199.                 
  2200.         return $nRet;   
  2201.     }
  2202.     
  2203.     function getBibleVerseID($sTranslationUrl$sBookUrl$nChapterNum=null$sVerseIndex=null)
  2204.     {                
  2205.         $sSql "SELECT v.id"
  2206.                 ." FROM biblebook b, biblechapter c, bibletranslation t, bibleverse v, canonicalbiblebook cb"                
  2207.                 ." WHERE t.url = '" trim(str_replace("'""''"$sTranslationUrl)) . "'"
  2208.                 ." and cb.url = '" trim(str_replace("'""''"$sBookUrl)) . "'";
  2209.         $sSql .= " and b.canonicalization_id = cb.id and b.translation_id = t.id and c.book_id = b.id and v.chapter_id = c.id";
  2210.         
  2211.         if($nChapterNum != null)
  2212.             $sSql .= " and c.ordering = " $nChapterNum;
  2213.         
  2214.         if($sVerseIndex != null)
  2215.         {
  2216.             if(!is_numeric($sVerseIndex))
  2217.             {
  2218.                 $filteredNumbers array_filter(preg_split("/\D+/"$sVerseIndex));
  2219.                 $verseNum reset($filteredNumbers);
  2220.                 $subverse trim($sVerseIndex$verseNum);
  2221.                 $sSql .= " and v.indexdisplay = '" trim(str_replace("'""''"$subverse)) . "'";
  2222.                 $sSql .= " and v.verse_id in (";
  2223.                 $sSql .= "SELECT v.id"
  2224.                 ." FROM biblebook b, biblechapter c, bibletranslation t, bibleverse v, canonicalbiblebook cb"                
  2225.                 ." WHERE t.url = '" trim(str_replace("'""''"$sTranslationUrl)) . "'"
  2226.                 ." and cb.url = '" trim(str_replace("'""''"$sBookUrl)) . "'";
  2227.                 $sSql .= " and b.canonicalization_id = cb.id and b.translation_id = t.id and c.book_id = b.id and v.chapter_id = c.id";
  2228.                 
  2229.                 if($nChapterNum != null)
  2230.                     $sSql .= " and c.ordering = " $nChapterNum;
  2231.                     
  2232.                 $sSql .= " and v.indexdisplay = '" $verseNum "')";    
  2233.             }
  2234.             else
  2235.                 $sSql .= " and v.indexdisplay = '" trim(str_replace("'""''"$sVerseIndex)) . "'";
  2236.         }    
  2237.         $sSql .= " order by c.ordering, v.indexdisplay limit 1";      
  2238.  //   echo $sSql;   
  2239.            $nRet null;
  2240.         $aTemp $this->getNativeQueryResults($sSql);
  2241.         if(count($aTemp) > 0
  2242.             $nRet $aTemp[0]['id'];        
  2243.                 
  2244.         return $nRet;   
  2245.     }
  2246.     
  2247.     function getNextChapter($chapter_id$nextbook_id=null)
  2248.     {                
  2249.         $sSql "SELECT c.id, t.url as translation_url, cb.url as book_url, c.ordering as chapter_order, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || t.url || '_' || cb.url  || '_' || c.ordering as chapter_multi_spec, b.name as book_name";
  2250.         $sSql .= " FROM bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb" 
  2251.                 ." WHERE c.book_id in (select book_id from biblechapter where id = " $chapter_id ") and c.ordering > (select ordering from biblechapter where id = " $chapter_id ") and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id order by c.ordering limit 1";
  2252.   //   echo $sSql."<br>";   
  2253.            $aRet = array();
  2254.         $aTemp $this->getNativeQueryResults($sSql);
  2255.         if(count($aTemp) > 0
  2256.             $aRet $aTemp[0]; 
  2257.         else
  2258.             $aRet $this->getNextChapterInNextBook($chapter_id$nextbook_id);            
  2259.                 
  2260.         return $aRet;   
  2261.     } 
  2262.         
  2263.     function getNextChapterInNextBook($chapter_id$nextbook_id)
  2264.     {        
  2265.         $aRet = array();        
  2266.         if($nextbook_id != '')
  2267.         {     
  2268.             $sSql "SELECT c.id, t.url as translation_url, cb.url as book_url, c.ordering as chapter_order, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || t.url || '_' || cb.url  || '_' || c.ordering as chapter_multi_spec, b.name as book_name";
  2269.             $sSql .= " FROM bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb" 
  2270.                     ." WHERE c.book_id = " $nextbook_id " and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id order by c.ordering limit 1";
  2271.     //     echo $sSql."<br>";   
  2272.                
  2273.             $aTemp $this->getNativeQueryResults($sSql);
  2274.             if(count($aTemp) > 0
  2275.                 $aRet $aTemp[0];        
  2276.         }
  2277.                 
  2278.         return $aRet;   
  2279.     } 
  2280.     
  2281.     function getPreviousChapter($chapter_id$prevbook_id=null)
  2282.     {                
  2283.         $sSql "SELECT c.id, t.url as translation_url, cb.url as book_url, c.ordering as chapter_order, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || t.url || '_' || cb.url  || '_' || c.ordering as chapter_multi_spec, b.name as book_name";
  2284.         $sSql .= " FROM bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb" 
  2285.                 ." WHERE c.book_id in (select book_id from biblechapter where id = " $chapter_id ") and c.ordering < (select ordering from biblechapter where id = " $chapter_id ") and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id order by c.ordering desc limit 1";
  2286.   //   echo $sSql."<br>";   
  2287.            $aRet = array();
  2288.         $aTemp $this->getNativeQueryResults($sSql);
  2289.         if(count($aTemp) > 0
  2290.             $aRet $aTemp[0];  
  2291.         else
  2292.             $aRet $this->getPreviousChapterInPreviousBook($chapter_id$prevbook_id);           
  2293.                 
  2294.         return $aRet;   
  2295.     } 
  2296.     
  2297.     function getPreviousChapterInPreviousBook($chapter_id$prevbook_id)
  2298.     {        
  2299.         $aRet = array();        
  2300.         if($prevbook_id != '')
  2301.         {     
  2302.             $sSql "SELECT c.id, t.url as translation_url, cb.url as book_url, c.ordering as chapter_order, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || t.url || '_' || cb.url  || '_' || c.ordering as chapter_multi_spec, b.name as book_name";
  2303.             $sSql .= " FROM bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb" 
  2304.                     ." WHERE c.book_id = " $prevbook_id " and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id order by c.ordering desc limit 1";
  2305.     //     echo $sSql."<br>";   
  2306.                
  2307.             $aTemp $this->getNativeQueryResults($sSql);
  2308.             if(count($aTemp) > 0
  2309.                 $aRet $aTemp[0];        
  2310.         }
  2311.                 
  2312.         return $aRet;   
  2313.     } 
  2314.     
  2315.     function getNextVerse($verse_id)
  2316.     {                
  2317.         $sSql "SELECT id FROM bibleverse"                 
  2318.                 ." WHERE verse_id = " $verse_id " and chapter_id in (select chapter_id from bibleverse where id = " $verse_id ") and indexdisplay like '%-%' limit 1";
  2319.   //   echo $sSql."<br>"; 
  2320.         $aTemp1 $this->getNativeQueryResults($sSql);
  2321.         if(count($aTemp1) > 0
  2322.             $verse_id $aTemp1[0]['id']; 
  2323.             
  2324.         $sSql "SELECT c.id, t.url as translation_url, cb.url as book_url, c.ordering as chapter_order, (case when v2.indexdisplay is not null and v.indexdisplay not like '%-%' then v.indexdisplay else null end) as subverse_index, (case when v2.indexdisplay is not null then case when v.indexdisplay like '%-%' then v2.indexdisplay else v2.indexdisplay || v.indexdisplay end else v.indexdisplay end) as verse_label, (case when v2.indexdisplay is not null then v2.indexdisplay else v.indexdisplay end) as verse_index, v.id as verse_id, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || t.url || '_' || cb.url || '_' || c.ordering || '_' || (case when v2.indexdisplay is not null then v2.indexdisplay else '' end) || v.indexdisplay as verse_multi_spec, b.name as book_name";
  2325.         $sSql .= " FROM bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb, bibleverse v" 
  2326.                 ." left join bibleverse v2 on v.verse_id = v2.id"
  2327.                 ." WHERE c.book_id in (select book_id from biblechapter where id in (select chapter_id from bibleverse where id = " $verse_id ")) and v.chapter_id = c.id and v.ordering > (select ordering from bibleverse where id = " $verse_id ") and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id and (v.verse_id is null or v.indexdisplay like '%-%') order by v.ordering limit 1";
  2328.    //  echo $sSql."<br>";   
  2329.            $aRet = array();
  2330.         $aTemp $this->getNativeQueryResults($sSql);
  2331.         if(count($aTemp) > 0
  2332.             $aRet $aTemp[0];        
  2333.                 
  2334.         return $aRet;   
  2335.     } 
  2336.     
  2337.     function getPreviousVerse($verse_id)
  2338.     {            
  2339.         $sSql "SELECT id FROM bibleverse"                 
  2340.                 ." WHERE verse_id = " $verse_id " and chapter_id in (select chapter_id from bibleverse where id = " $verse_id ") and indexdisplay like '%-%' limit 1";
  2341.   //   echo $sSql."<br>"; 
  2342.         $aTemp1 $this->getNativeQueryResults($sSql);
  2343.         if(count($aTemp1) > 0
  2344.             $verse_id $aTemp1[0]['id']; 
  2345.         
  2346.         $sSql "SELECT c.id, t.url as translation_url, cb.url as book_url, c.ordering as chapter_order, (case when v2.indexdisplay is not null and v.indexdisplay not like '%-%' then v.indexdisplay else null end) as subverse_index, (case when v2.indexdisplay is not null then case when v.indexdisplay like '%-%' then v2.indexdisplay else v2.indexdisplay || v.indexdisplay end else v.indexdisplay end) as verse_label, (case when v2.indexdisplay is not null then v2.indexdisplay else v.indexdisplay end) as verse_index, v.id as verse_id, '" $this->MULTI_URL_INDICATOR_BIBLE "' || '_' || t.url || '_' || cb.url || '_' || c.ordering || '_' || (case when v2.indexdisplay is not null then v2.indexdisplay else '' end) || v.indexdisplay as verse_multi_spec, b.name as book_name";
  2347.         $sSql .= " FROM bibletranslation t, biblebook b, biblechapter c, canonicalbiblebook cb, bibleverse v" 
  2348.                 ." left join bibleverse v2 on v.verse_id = v2.id"
  2349.                 ." WHERE c.book_id in (select book_id from biblechapter where id in (select chapter_id from bibleverse where id = " $verse_id ")) and v.chapter_id = c.id and v.ordering < (select ordering from bibleverse where id = " $verse_id ") and c.book_id = b.id and b.canonicalization_id = cb.id and b.translation_id = t.id and (v.verse_id is null or v.indexdisplay like '%-%') order by v.ordering desc limit 1";
  2350.    //  echo $sSql."<br>";   
  2351.            $aRet = array();
  2352.         $aTemp $this->getNativeQueryResults($sSql);
  2353.         if(count($aTemp) > 0
  2354.             $aRet $aTemp[0];        
  2355.                 
  2356.         return $aRet;   
  2357.     } 
  2358.     
  2359.     function getTextToSpeech($vLanguageId)
  2360.     {                
  2361.         $sSql "SELECT t.name"
  2362.                 ." FROM texttospeech t, texttospeechlanguage tl"                
  2363.                 ." WHERE tl.language_id = " $vLanguageId
  2364.                 ." and t.id = tl.tts_id";
  2365.         $sSql .= " order by tl.is_standard desc limit 1";      
  2366.  //   echo $sSql;   
  2367.            $sRet null;
  2368.         $aTemp $this->getNativeQueryResults($sSql);
  2369.         if(count($aTemp) > 0
  2370.             $sRet $aTemp[0]['name'];        
  2371.                 
  2372.         return $sRet;   
  2373.     }
  2374.     
  2375.     function checkBookInfo($book_id$chapterStartIndex$chapterEndIndex$verseStartIndex$verseEndIndex)
  2376.     {
  2377.         $aRet = array();
  2378.         // check start chapter
  2379.         $sSql "SELECT ordering FROM biblechapter"                
  2380.                 ." WHERE book_id = " $book_id " and ordering = " $chapterStartIndex " limit 1";
  2381.          
  2382.         $aTemp $this->getNativeQueryResults($sSql);        
  2383.         if(count($aTemp) > 0
  2384.             $aRet['chapterStartIndex'] = current($aTemp[0]); 
  2385.         else
  2386.         {
  2387.             $sSql "SELECT min(ordering) FROM biblechapter"                
  2388.                 ." WHERE book_id = " $book_id;
  2389.             $aTemp $this->getNativeQueryResults($sSql);            
  2390.             if(count($aTemp) > 0
  2391.                 $aRet['chapterStartIndex'] = current($aTemp[0]);
  2392.         }    
  2393.         
  2394.         // check end chapter
  2395.         if($chapterEndIndex != null)
  2396.         {
  2397.             $sSql "SELECT ordering FROM biblechapter"                
  2398.                     ." WHERE book_id = " $book_id " and ordering = " $chapterEndIndex " limit 1";
  2399.             $aTemp $this->getNativeQueryResults($sSql);        
  2400.             if(count($aTemp) > 0
  2401.                 $aRet['chapterEndIndex'] = current($aTemp[0]); 
  2402.             else
  2403.             {
  2404.                 $aRet['chapterEndIndex'] = $aRet['chapterStartIndex'];
  2405.             }
  2406.         }
  2407.                         
  2408.         // check start verse
  2409.         $sSql "SELECT v.indexdisplay FROM bibleverse v, biblechapter c"                
  2410.                 ." WHERE c.book_id = " $book_id " and c.ordering = " $aRet['chapterStartIndex']
  2411.                 ." and v.chapter_id = c.id and v.indexdisplay = '" $verseStartIndex "' limit 1";
  2412.    //    echo $sSql;          
  2413.         $aTemp $this->getNativeQueryResults($sSql);        
  2414.         if(count($aTemp) > 0
  2415.             $aRet['verseStartIndex'] = current($aTemp[0]); 
  2416.         else
  2417.         {
  2418.             $sSql "SELECT v.indexdisplay FROM bibleverse v, biblechapter c"                
  2419.                 ." WHERE book_id = " $book_id " and c.ordering = " $aRet['chapterStartIndex']
  2420.                 ." and v.chapter_id = c.id order by v.ordering limit 1";
  2421.      //      echo $sSql;      
  2422.             $aTemp $this->getNativeQueryResults($sSql);            
  2423.             if(count($aTemp) > 0)
  2424.             {             
  2425.                 $aRet['verseStartIndex'] = current($aTemp[0]);
  2426.             }    
  2427.         }    
  2428.         
  2429.         // check end verse
  2430.         if($verseEndIndex != null && isset($aRet['chapterEndIndex']) && $aRet['chapterEndIndex'] != null)
  2431.         {
  2432.             $sSql "SELECT v.indexdisplay FROM bibleverse v, biblechapter c"                
  2433.                 ." WHERE c.book_id = " $book_id " and c.ordering = " $aRet['chapterEndIndex']
  2434.                 ." and v.chapter_id = c.id and v.indexdisplay = '" $verseEndIndex "' limit 1";
  2435.             $aTemp $this->getNativeQueryResults($sSql);        
  2436.             if(count($aTemp) > 0
  2437.                 $aRet['verseEndIndex'] = current($aTemp[0]); 
  2438.             else
  2439.             {
  2440.                 $sSql "SELECT v.indexdisplay FROM bibleverse v, biblechapter c"                
  2441.                     ." WHERE book_id = " $book_id " and c.ordering = " $aRet['chapterEndIndex']
  2442.                     ." and v.chapter_id = c.id order by v.ordering limit 1";
  2443.                 $aTemp $this->getNativeQueryResults($sSql);            
  2444.                 if(count($aTemp) > 0
  2445.                     $aRet['verseEndIndex'] = current($aTemp[0]);                    
  2446.             }
  2447.         }            
  2448.         
  2449.         return $aRet;
  2450.     }
  2451.     
  2452.     function getChapterExplanationsForText($translation)
  2453.     {        
  2454.         $nCurrTranslationID $translation->getId();
  2455.         $nLanguageID $translation->getLanguage()->getId();
  2456.         $sSql "select distinct on (chapter_order) * from (SELECT t.id as translation_id, t.url as translation_url, bs.name as explanationtitle, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, cbc.ordering as chapter_order, case when t.language_id = " $nLanguageID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 end end as lang_order, case when t.id = " $nCurrTranslationID " then 1 else case when t.language_id = " $nLanguageID " then 2 else case when t.islanguagedefault then 3 else 4 end end end as trans_order, w.id as work_id, bs.id as story_id, t.language_id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name"
  2457.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs, canonicalbiblechapter cbc, language l"
  2458.                 ." WHERE bs.chapter_id in (select id from canonicalbiblechapter where book_id in (select book_id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $translation->getWork()->getId() . " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id)) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  2459.                 ." and cbc.id = bs.chapter_id and t.language_id = l.id and w.ispublic AND t.ispublic order by cbc.ordering, lang_order, trans_order, t.is_modern desc, sw.ordering) as t";
  2460.   //    echo $sSql . "<br>";          
  2461.         return $this->getNativeQueryResults($sSql); 
  2462.     }
  2463.     
  2464.     function getChapterExplanationsForNav($translation)
  2465.     {        
  2466.         $nTranslationID $translation->getId();
  2467.         $nLanguageID $translation->getLanguage()->getId();
  2468.         $sSql "select distinct on (chapter_order) * from (SELECT t.id as translation_id, t.url as translation_url, bs.name as explanationtitle, cbc.ordering as chapter_order, case when t.language_id = " $nLanguageID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 end end as lang_order, case when t.id = " $nTranslationID " then 1 else case when t.language_id = " $nLanguageID " then 2 else case when t.islanguagedefault then 3 else 4 end end end as trans_order, cb.id as book_id"
  2469.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs, canonicalbiblechapter cbc, canonicalbiblebook cb"
  2470.                 ." WHERE bs.chapter_id in (select id from canonicalbiblechapter where book_id in (select book_id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $translation->getWork()->getId() . " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id)) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  2471.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic and cbc.book_id = cb.id order by cbc.ordering, lang_order, trans_order, t.is_modern desc, sw.ordering) as t";
  2472.     //  echo $sSql . "<br>";          
  2473.         return $this->getNativeQueryResults($sSql); 
  2474.     }
  2475.     
  2476.     function getChapterExplanationsForTextForCombo($translation)
  2477.     {        
  2478.         $nCurrTranslationID $translation->getId();
  2479.         $nLanguageID $translation->getLanguage()->getId();
  2480.         $nCurrWorkID $translation->getWork()->getId();
  2481.         $sSql "SELECT t.id as translation_id, t.url as translation_url, w.title as explanationtitle, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, case when t.language_id = " $nLanguageID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 end end as lang_order, case when t.id = " $nCurrTranslationID " then 1 else case when t.islanguagedefault then 2 else 3 end end as trans_order, w.id as work_id, t.is_modern"
  2482.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs, canonicalbiblechapter cbc"
  2483.                 ." WHERE bs.chapter_id in (select cbc2.id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $nCurrWorkID " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  2484.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic order by lang_order, t.is_modern desc, trans_order";
  2485.     //  echo $sSql . "<br>";          
  2486.         return $this->getNativeQueryResults($sSql); 
  2487.     }  
  2488.     
  2489.     function getFirstCBook($nTranslationID)
  2490.     {                
  2491.         $sSql "SELECT cb.id"
  2492.                 ." FROM language l, bibletranslation t, biblebook b, canonicalbiblebook cb"
  2493.                  ." WHERE t.id = " $nTranslationID;                    
  2494.          $sSql .= " and b.canonicalization_id = cb.id and b.translation_id = t.id and t.enabled and t.language_id = l.id order by cb.ordering limit 1";
  2495.  //    echo $sSql."<br>";   
  2496.            $aRet = array();
  2497.         $aTemp $this->getNativeQueryResults($sSql);
  2498.         if(count($aTemp) > 0
  2499.             $aRet $aTemp[0];        
  2500.                 
  2501.         return $aRet;   
  2502.     }
  2503.     
  2504.     function getConceptUrl($vWorkId)
  2505.     {                
  2506.         $sSql "SELECT c.url"
  2507.                 ." FROM expositionwork w, work_category wc, concept_work cl, expositiontranslation t, concept c" 
  2508.                 ." WHERE w.id = " $vWorkId ." and wc.work_id = w.id"
  2509.                 ." and t.work_id = w.id and cl.work_id = w.id and c.id = cl.concept_id"
  2510.                 ." and wc.category_id = " $this->CATEGORY_ID_CONCEPT;
  2511.  //   echo $sSql;   
  2512.            $sRet null;
  2513.         $aTemp $this->getNativeQueryResults($sSql);
  2514.         if(count($aTemp) > 0
  2515.             $sRet $aTemp[0]['url'];        
  2516.                 
  2517.         return $sRet;   
  2518.     }
  2519.     
  2520.     function getTopPathList($locale$vLimit=null)
  2521.     {
  2522.         return $this->getTopPathListFromDB($localetrue$vLimit);
  2523.     }
  2524.     
  2525.     function getTopPathListFromDB($locale$vIsFeatured$vLimit)
  2526.     {
  2527.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  2528.         $sSql "SELECT t.id, (case when tl.title is not null then tl.title else t.default_title end) AS title, (case when tl.description is not null then tl.description else t.default_description end) as description, t.url, i.file as image_file, i.title as image_title, (case when title_color is not null then title_color else '" $this->DEFAULT_PATH_TITLE_COLOR "' end) as title_color, (case when i.height > i.width then ' portrait' else '' end) as image_class"
  2529.                 ." FROM image i, expositiontopicgroup t";  
  2530.              
  2531.        //      if($this->showEnglishTrans($nLanguageID))   
  2532.                  $sSql .= " left join ";
  2533.         //     else
  2534.         //         $sSql .= " join ";    
  2535.              $sSql .= " (select tl1.expositiontopicgroup_id, tl1.title, tl1.description from expositiontopicgroup_language tl1, language l where l.shortcode = '" trim(str_replace("'""''"$locale)) . "' and l.id = tl1.language_id) as tl on t.id = tl.expositiontopicgroup_id"              
  2536.                 ." WHERE t.image_id = i.id and t.url is not null and t.url <> '' and t.id in (select expositiontopicgroup_id from expositiontopic_group)";
  2537.         
  2538.         if($vIsFeatured)
  2539.              $sSql .= " and t.is_featured";       
  2540.         else
  2541.              $sSql .= " and not t.is_featured";       
  2542.                 
  2543.         $sSql .= " ORDER BY t.display_order";
  2544.         
  2545.         if($vLimit 0)
  2546.              $sSql .= " limit " $vLimit
  2547.              
  2548.    //   echo $sSql . "<br>";          
  2549.         return $this->getNativeQueryResults($sSql);
  2550.     }  
  2551.     
  2552.     function getSubPathList($toppathurl$locale)
  2553.     {
  2554.         return $this->getSubPathListFromDB($toppathurl$localetrue);
  2555.     }
  2556.     
  2557.     function getSubPathListFromDB($TopPathUrl$locale$vIsFeatured)
  2558.     {
  2559.         $sSql "SELECT (case when tl.title is not null then tl.title else t.name end) AS title, (case when tl.description is not null then tl.description else t.default_description end) as description, t.url, i.file as image_file, i.title as image_title, (case when i.height > i.width then ' portrait' else '' end) as image_class"
  2560.                 ." FROM image i, expositiontopicgroup tg, expositiontopic_group t_g, expositiontopic t" 
  2561.                 ." left join (select tl1.expositiontopic_id, tl1.title, tl1.description from expositiontopic_language tl1, language l where l.shortcode = '" trim(str_replace("'""''"$locale)) . "' and l.id = tl1.language_id) as tl on t.id = tl.expositiontopic_id"  
  2562.                 ." WHERE t.image_id = i.id and t.url is not null and t.url <> '' and t.id = t_g.expositiontopic_id "
  2563.                 ." and tg.id = t_g.expositiontopicgroup_id and tg.url = '" trim(str_replace("'""''"$TopPathUrl)) . "'"
  2564.                 ." and t.id in (select topic_id from work_topic)";
  2565.         
  2566.         if($vIsFeatured)
  2567.              $sSql .= " and t_g.is_featured";       
  2568.         else
  2569.              $sSql .= " and not t_g.is_featured";        
  2570.                 
  2571.         $sSql .= " ORDER BY t_g.display_order";
  2572.   //    echo $sSql . "<br>";          
  2573.         return $this->getNativeQueryResults($sSql);
  2574.     }  
  2575.     
  2576.     function getTopPathInfo($TopPathUrl$locale)
  2577.     {
  2578.         $sSql "SELECT (case when tl.title is not null then tl.title else t.default_title end) AS title, (case when tl.description is not null then tl.description else t.default_description end) as description, (case when title_color is not null then title_color else '" $this->DEFAULT_PATH_TITLE_COLOR "' end) as title_color"
  2579.                 ." FROM expositiontopicgroup t" 
  2580.                  ." left join (select tl1.expositiontopicgroup_id, tl1.title, tl1.description from expositiontopicgroup_language tl1, language l where l.shortcode = '" trim(str_replace("'""''"$locale)) . "' and l.id = tl1.language_id) as tl on t.id = tl.expositiontopicgroup_id"                
  2581.                 ." WHERE url = '" trim(str_replace("'""''"$TopPathUrl)) . "'";
  2582.  //  echo $sSql . "<br>";             
  2583.         $aRet = array();
  2584.         $aTemp $this->getNativeQueryResults($sSql);
  2585.         if(count($aTemp) > 0
  2586.             $aRet $aTemp[0];        
  2587.                 
  2588.         return $aRet
  2589.     }  
  2590.     
  2591.     function getExplanationListForTopic($TopicUrl,$locale)
  2592.     {       
  2593.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  2594.         
  2595.         $sLangStr '';
  2596.         if($nLanguageID != null)
  2597.         {
  2598.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  2599.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  2600.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  2601.                 
  2602.             $sLangStr .= ' 3 end';
  2603.             
  2604.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  2605.                 $sLangStr .= ' end';
  2606.                 
  2607.             $sLangStr .= ' as language_order';        
  2608.         }
  2609.         else
  2610.             $sLangStr .= '1 as language_order';    
  2611.              
  2612.         $sSql "select * from (select distinct on (work_id) * from (SELECT w.id as work_id,"
  2613.                 ."t.translatedtitle AS title, t.description, t.url, wc.category_id, bsw.story_id, bsw.story_url,"
  2614.                 ." ti.image_file, ti.image_title, ti.image_class, wt.display_order, " $sLangStr 
  2615.                 ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  2616.                 ." FROM work_topic wt, expositiontopic et, expositiontranslation t left join vexpositiontranslationimage ti on t.id = ti.translation_id join expositionwork w on t.work_id = w.id left join work_category wc on w.id = wc.work_id"
  2617.                 ."  left join (select bs.id, bs.url as story_url, sw.work_id, sw.story_id from story_work sw, (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE ") as bs where bs.id = sw.story_id) bsw on w.id = bsw.work_id"
  2618.                 ." WHERE et.url = '" trim(str_replace("'""''"$TopicUrl)) . "'"
  2619.                 ." and wt.topic_id = et.id and wt.work_id = t.work_id"
  2620.                 ." AND t.ispublic AND w.ispublic and t.url is not null and t.url <> ''" 
  2621.                 ." ORDER BY language_order, lang_default_order) as t1) as t where language_order < 3"
  2622.                 ." ORDER BY display_order";        
  2623.              
  2624.      //   echo $sSql . "<br>";          
  2625.         return $this->getNativeQueryResults($sSql);
  2626.     }  
  2627.     
  2628.     function getSubPathInfo($SubPathUrl$locale)
  2629.     {
  2630.         $sSql "SELECT (case when tl.title is not null then tl.title else t.name end) AS title, (case when tl.description is not null then tl.description else t.default_description end) as description"
  2631.                 ." FROM expositiontopic t"
  2632.                 ." left join (select tl1.expositiontopic_id, tl1.title, tl1.description from expositiontopic_language tl1, language l where l.shortcode = '" trim(str_replace("'""''"$locale)) . "' and l.id = tl1.language_id) as tl on t.id = tl.expositiontopic_id"                
  2633.                 ." WHERE t.url = '" trim(str_replace("'""''"$SubPathUrl)) . "'";
  2634.     // echo $sSql."<br>";            
  2635.         $aRet = array();
  2636.         $aTemp $this->getNativeQueryResults($sSql);
  2637.         if(count($aTemp) > 0
  2638.             $aRet $aTemp[0];        
  2639.                 
  2640.         return $aRet
  2641.     } 
  2642.     
  2643.     function getExplanationListForTopAndSubPath($TopPathUrl$SubPathUrl$locale)
  2644.     {                
  2645.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  2646.         
  2647.         $sLangStr '';
  2648.         if($nLanguageID != null)
  2649.         {
  2650.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  2651.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  2652.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  2653.                 
  2654.             $sLangStr .= ' 3 end';
  2655.             
  2656.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  2657.                 $sLangStr .= ' end';
  2658.                 
  2659.             $sLangStr .= ' as language_order';        
  2660.         }
  2661.         else
  2662.             $sLangStr .= '1 as language_order';    
  2663.     
  2664.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id,"
  2665.                 ." t.translatedtitle AS title, t.description, t.url, wc.category_id, bsw.story_id,"
  2666.                 ." bsw.story_url, ti.image_file, ti.image_title, ti.image_class, wt.display_order, " $sLangStr 
  2667.                 ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  2668.                 ." FROM work_topic wt, expositiontopic et, work_topicgroup wtg, expositiontopicgroup tg, expositiontranslation t left join vexpositiontranslationimage ti on t.id = ti.translation_id join expositionwork w on t.work_id = w.id left join work_category wc on w.id = wc.work_id"
  2669.                 ."  left join (select bs.id, bs.url as story_url, sw.work_id, sw.story_id from story_work sw, (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE ") as bs where bs.id = sw.story_id) bsw on w.id = bsw.work_id"
  2670.                 ." WHERE et.url = '" trim(str_replace("'""''"$SubPathUrl)) . "'"
  2671.                 ." and tg.url = '" trim(str_replace("'""''"$TopPathUrl)) . "'"
  2672.                 ." and wt.topic_id = et.id and wt.work_id = t.work_id"
  2673.                 ." and wtg.topicgroup_id = tg.id and wtg.work_id = t.work_id"
  2674.                 ." AND t.ispublic AND w.ispublic and t.url is not null and t.url <> ''"                
  2675.                 ." ORDER BY w.id, language_order, lang_default_order) as t where language_order < 3"
  2676.                 ." ORDER BY display_order";       
  2677.                 
  2678.     //    echo $sSql . "<br>";          
  2679.         return $this->getNativeQueryResults($sSql);
  2680.     }  
  2681.     
  2682.     function getTopicList($locale)
  2683.     {
  2684.         $sSql "SELECT (case when tl.title is not null then tl.title else t.name end) AS title, (case when tl.description is not null then tl.description else t.default_description end) as description, t.url, i.file as image_file, i.title as image_title, (case when i.height > i.width then ' portrait' else '' end) as image_class"
  2685.                 ." FROM image i, expositiontopic t"  
  2686.                 ." left join (select tl1.expositiontopic_id, tl1.title, tl1.description from expositiontopic_language tl1, language l where l.shortcode = '" trim(str_replace("'""''"$locale)) . "' and l.id = tl1.language_id) as tl on t.id = tl.expositiontopic_id"              
  2687.                 ." WHERE t.image_id = i.id and t.url is not null and t.url <> ''"
  2688.                 ." ORDER BY t.display_order";
  2689.                   
  2690.    //   echo $sSql . "<br>";        
  2691.         return $this->getNativeQueryResults($sSql);
  2692.     } 
  2693.     
  2694.     function HasBibleBookForTrans($story_id$bible_translation_url)
  2695.     {        
  2696.         $bRet false;
  2697.             
  2698.         $sSql "SELECT bt.id "
  2699.                 ." FROM (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE ") as bs, canonicalbibleverse cv, canonicalbibleverse_bibleverse cvv, "
  2700.                 ." canonicalbiblechapter scc, expositionwork w, expositiontranslation t, story_work sw," 
  2701.                 ." biblechapter c, biblebook b, bibletranslation bt, canonicalbiblebook cb, bibleverse v" 
  2702.                 ." WHERE bs.id = " $story_id " and bt.url = '" trim(str_replace("'""''"$bible_translation_url)) . "' and w.ispublic and t.ispublic"
  2703.                 ." and v.id = cvv.bibleverse_id and cv.id = cvv.canonicalbibleverse_id"     
  2704.                 ." and bs.startverse_id = cv.id"                 
  2705.                 ." and cv.chapter_id = scc.id and v.verse_id is null"
  2706.                 ." and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"                
  2707.                 ." and v.chapter_id = c.id and b.id = c.book_id and b.translation_id=bt.id and scc.book_id = cb.id"
  2708.                 ." limit 1";
  2709. //     echo $sSql."<br>";             
  2710.         $aTemp $this->getNativeQueryResults($sSql);
  2711.         if(count($aTemp) > 0
  2712.             $bRet true;              
  2713.         
  2714.          return $bRet;    
  2715.     }
  2716.            
  2717.     // get footnote popup text for footnotes that repeat after the first footnote 
  2718.     // (e.g. footnote '1' after the first one) 
  2719.     // The repeated footnotes have no hyperlinks, show them as plain text 
  2720.     function getPassageFootnotes($passage_id,$translation_id)
  2721.     {      
  2722.         $sSql "select di1.text as footnote, array_to_string(array_agg(di3.text order by di3.ordering),' ') as footnote_text from expositiondisplayitem di1, (select di2.* from expositiondisplayitem di2, expositiontranslationtext tt, expositiontextunit tu where tu.passage_id = " $passage_id " and tt.translation_id = " $translation_id;
  2723.         $sSql .= " and tu.id = tt.placement_id and di2.container_id = tt.id";
  2724.         $sSql .= " order by di2.ordering) as di3 where di3.containingitem_id = di1.id group by di1.text";
  2725.   //   echo $sSql."<br>";  
  2726.           $aRet = array(); 
  2727.            $aTemp $this->getNativeQueryResults($sSql); 
  2728.            $nLen count($aTemp);
  2729.            for($i=0;$i<$nLen;$i++)
  2730.            {                              
  2731.                $sTempText $aTemp[$i]["footnote_text"];
  2732.                $nPosDot strpos($sTempText'.');
  2733.                $sCheckNum substr($sTempText0$nPosDot);
  2734.                if(is_numeric($sCheckNum))
  2735.                    $sTempText trim(substr($sTempText$nPosDot+1));
  2736.                
  2737.                $sTempText1 "<i>"nl2br($sTempText) . "</i>"
  2738.                $aRet[$aTemp[$i]["footnote"]] = $sTempText1;
  2739.                
  2740.                // For quick view page
  2741.                $sTempText2 str_replace('\n'' '$sTempText);
  2742.                $aRet[$aTemp[$i]["footnote"]."q"] = $sTempText2;
  2743.            }
  2744.              
  2745.         return $aRet
  2746.     }
  2747.     
  2748.     function getReadingPlanList($user_id$locale)
  2749.     {
  2750.         return $this->getReadingPlanListFromDB($user_id$localetrue);
  2751.     }
  2752.     
  2753.     function getReadingPlanListFromDB($user_id$locale$vIsFeatured)
  2754.     {
  2755.         $bUser=!empty($user_id);
  2756.         $sSql "SELECT (case when rl.name is not null then rl.name else r.name end) AS title, (case when rl.intro is not null then rl.intro else r.intro end) as description, r.url, i.file as image_file, i.title as image_title, (case when i.height > i.width then ' portrait' else '' end) as image_class,";
  2757.         if($bUser)
  2758.         {
  2759.             $sSql .= " ur.status_id";
  2760.         }
  2761.         else
  2762.         {
  2763.             $sSql .= " null as status_id";
  2764.         } 
  2765.         $sSql .= " FROM image i, readingplan r"   
  2766.                 ." left join (select rl1.readingplan_id, rl1.name, rl1.intro, rl1.description from readingplan_language rl1, language l where l.shortcode = '" trim(str_replace("'""''"$locale)) . "' and l.id = rl1.language_id) as rl on r.id = rl.readingplan_id";
  2767.         if($bUser)
  2768.         {
  2769.             $sSql .= " left join (select * from user_readingplan where user_id = " $user_id ") ur on r.id = ur.readingplan_id";
  2770.         }       
  2771.                              
  2772.         $sSql .= " WHERE r.image_id = i.id and r.url is not null and r.id in (select readingplan_id from readingplanstep)";
  2773.         
  2774.         if($vIsFeatured)
  2775.              $sSql .= " and r.is_featured";       
  2776.         else
  2777.              $sSql .= " and not r.is_featured";       
  2778.         
  2779.         if($bUser)
  2780.         {
  2781.             $sSql .= " ORDER BY (case when ur.status_id = 2 then 1 else case when ur.status_id is null or ur.status_id <> 4 then 2 else 3 end end), ordering";
  2782.         }
  2783.         else
  2784.         {        
  2785.             $sSql .= " ORDER BY ordering";
  2786.         }
  2787.    //   echo $sSql . "<br>";          
  2788.         return $this->getNativeQueryResults($sSql);
  2789.     }  
  2790.     
  2791.     function getReadingPlanInfo($readingPlanUrl$locale)
  2792.     {
  2793.         $sSql "SELECT r.id, count(rs.id) as step_count, (case when rl.name is not null then rl.name else r.name end) AS title, (case when rl.description is not null then rl.description else r.description end) as description, url, avg_daily_read_time, i.file as image_file, i.title as image_title, (case when i.height > i.width then ' portrait' else '' end) as image_class"
  2794.                 ." FROM image i, readingplan r" 
  2795.                 ." left join readingplanstep rs on r.id = rs.readingplan_id" 
  2796.                  ." left join (select rl1.readingplan_id, rl1.name, rl1.description from readingplan_language rl1, language l where l.shortcode = '" trim(str_replace("'""''"$locale)) . "' and l.id = rl1.language_id) as rl on r.id = rl.readingplan_id"                
  2797.                 ." WHERE url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  2798.                 ." and r.image_id = i.id group by r.id, rl.name, r.name, rl.description, r.description, url, i.file, i.title, i.height, i.width" ;
  2799.   // echo $sSql . "<br>";             
  2800.         $aRet = array();
  2801.         $aTemp $this->getNativeQueryResults($sSql);
  2802.         if(empty($aTemp))
  2803.         {
  2804.             $sSql "SELECT r.id, count(rs.id) as step_count, r.name AS title, r.description, url, avg_daily_read_time, i.file as image_file, i.title as image_title, (case when i.height > i.width then ' portrait' else '' end) as image_class"
  2805.                 ." FROM image i, readingplan r" 
  2806.                 ." left join readingplanstep rs on r.id = rs.readingplan_id"
  2807.                 ." WHERE url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  2808.                 ." and r.image_id = i.id group by r.id, r.name, r.description, url, i.file, i.title, i.height, i.width" ;
  2809.     //   echo $sSql . "<br>";             
  2810.             $aRet = array();
  2811.             $aTemp $this->getNativeQueryResults($sSql);
  2812.         }
  2813.         
  2814.         if(count($aTemp) > 0
  2815.         {
  2816.             $aRet $aTemp[0]; 
  2817.             $aRet['first_order'] = $this->getReadingPlanFirstStepOrder($readingPlanUrl);       
  2818.         }
  2819.                 
  2820.         return $aRet
  2821.     }  
  2822.     
  2823.     function getUserStepInfo($readingPlanUrl$UserID)
  2824.     {
  2825.         $sSql "SELECT ur.completed_step_id, rps.name as current_status, ur.reminder_option_id FROM readingplan r, readingplanstatus rps, user_readingplan ur" 
  2826.                 ." where ur.user_id = " $UserID
  2827.                 ." and r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  2828.                 ." and r.id = ur.readingplan_id"                 
  2829.                  ." and rps.id = ur.status_id";
  2830. //   echo $sSql . "<br>";             
  2831.         $aRet = array();
  2832.         $aTemp $this->getNativeQueryResults($sSql);
  2833.         if(count($aTemp) > 0)
  2834.         { 
  2835.             $aRet $aTemp[0];
  2836.         
  2837.             $nStepOrder null;
  2838.             $nCompletedStepID $aRet['completed_step_id'];    
  2839.             if(!empty($nCompletedStepID))
  2840.             {
  2841.                 $sSql "SELECT ordering FROM readingplanstep"
  2842.                     ." where id = " $nCompletedStepID;
  2843.                 $nStepOrder $this->getSingleData($sSql);    
  2844.             }
  2845.             
  2846.             $aRet['completed_step_order'] =    $nStepOrder;  
  2847.         }     
  2848.                 
  2849.         return $aRet
  2850.     } 
  2851.     
  2852.     function getUserReadingPlanInfo($readingPlanUrl$UserID$request)
  2853.     {
  2854.         $aRet = array();
  2855.         
  2856.         $locale $request->getLocale();    
  2857.         $nLanguageID $this->getLanguageIDByShortCode($locale); 
  2858.         
  2859.         $bHasUserStep false;
  2860.         if($UserID != '')
  2861.         {
  2862.             $aCompletedStepInfo $this->getUserStepInfo($readingPlanUrl$UserID);
  2863.       //  print_r($aCompletedStepInfo);               
  2864.             if(!empty($aCompletedStepInfo))
  2865.             {
  2866.                 $sSql "SELECT rs.name as step_name, rs.ordering as step_order"
  2867.                         ." FROM readingplan r, (select rsa.id, case when rsl.name is null then rsa.name else rsl.name end as name, rsa.readingplan_id, rsa.startverse_id, rsa.endverse_id, rsa.ordering, case when rsl.text is null then rsa.text else rsl.text end as text from readingplanstep rsa left join (select * from readingplanstep_language where language_id = " .$nLanguageID ") rsl on rsa.id = rsl.readingplanstep_id) rs"
  2868.                         ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  2869.                         ." and r.id = rs.readingplan_id"                        
  2870.                         ." and rs.id not in (select readingplanstep_id from user_readingplanstep urs, user_readingplan ur where ur.user_id = " $UserID " and ur.id = urs.user_readingplan_id)"
  2871.                         ." order by rs.ordering limit 1";
  2872.          //  echo $sSql . "<br>";  
  2873.                 $aTemp $this->getNativeQueryResults($sSql);
  2874.                 if(count($aTemp) > 0
  2875.                 {
  2876.                     $aRet $aTemp[0];                    
  2877.                     $aRet['step_complete'] = false;
  2878.                     $bHasUserStep true;
  2879.                 }
  2880.                 else
  2881.                 {            
  2882.                     $aRet['step_complete'] = true;
  2883.                     $bHasUserStep true;    
  2884.                     $sSql "SELECT min(rs.ordering) as step_order"
  2885.                         ." FROM readingplan r, readingplanstep rs"
  2886.                         ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  2887.                         ." and r.id = rs.readingplan_id";
  2888.                     $nStepOrder $this->getSingleData($sSql);
  2889.                     $aRet['step_order'] = $nStepOrder;                                   
  2890.                 }    
  2891.                 $aRet['current_status'] = $aCompletedStepInfo['current_status'];
  2892.                 $aRet['reminder_option_id'] = $aCompletedStepInfo['reminder_option_id'];
  2893.             }            
  2894.         }   
  2895.         
  2896.         if(!$bHasUserStep)
  2897.         {
  2898.             $sSql "SELECT min(rs.ordering) as step_order"
  2899.                         ." FROM readingplan r, readingplanstep rs"
  2900.                         ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  2901.                         ." and r.id = rs.readingplan_id";
  2902.           // echo $sSql . "<br>";  
  2903.                 $aTemp $this->getNativeQueryResults($sSql);
  2904.                 if(count($aTemp) > 0
  2905.                 {                
  2906.                     $aRet $aTemp[0];                                          
  2907.                 }    
  2908.         }     
  2909.         return $aRet
  2910.     }  
  2911.     
  2912.     function getReadingPlanStepInfoForBible($readingPlanUrl$stepOrder$request)
  2913.     {
  2914.         $locale $request->getLocale();    
  2915.         $nLanguageID $this->getLanguageIDByShortCode($locale);    
  2916.                 
  2917.         $sSql "SELECT rs.id, rs.name, rs.text, rs.closing_text, rs.image_file, rs.image_title, rs.video_link, rs.youtube_id, rs.video_notice, ";
  2918.         $sSql .= "case when rl.name is null then r.name else rl.name end";        
  2919.         $sSql .= " as plan_title, rs.ordering as step_order, cb1.id as book_id, cc1.ordering as start_chapter_order, cv1.ordering as start_verse_order, cc2.ordering as end_chapter_order, cv2.ordering as end_verse_order FROM canonicalbibleverse cv1, canonicalbiblechapter cc1, canonicalbiblebook cb1, canonicalbibleverse cv2, canonicalbiblechapter cc2, ";
  2920.         $sSql .= " (select rsa.id, case when rsl.name is null then rsa.name else rsl.name end as name, rsa.readingplan_id, rsa.startverse_id, rsa.endverse_id, rsa.ordering, case when rsl.text is null then rsa.text else rsl.text end as text, case when rsl.closing_text is null then rsa.closing_text else rsl.closing_text end as closing_text, i.file as image_file, i.title as image_title, e.location as video_link, e.youtube_id, e.notice as video_notice from readingplanstep rsa left join (select * from readingplanstep_language where language_id = " .$nLanguageID ") rsl on rsa.id = rsl.readingplanstep_id left join image i on rsa.image_id = i.id left join (select * from embed where visibilitydefault) e on rsa.embed_id = e.id) rs, ";
  2921.             $sSql .= " readingplan r left join (select * from readingplan_language where language_id = " .$nLanguageID ") rl on r.id = rl.readingplan_id ";            
  2922.                  
  2923.         $sSql .= " where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  2924.                 ." and r.id = rs.readingplan_id"
  2925.                  ." and rs.ordering = " $stepOrder
  2926.                  ." and cv1.id = rs.startverse_id and cv1.chapter_id = cc1.id"                                
  2927.                 ." and cb1.id = cc1.book_id"                
  2928.                 ." and cv2.id = rs.endverse_id and cv2.chapter_id = cc2.id";
  2929.   // echo $sSql . "<br>";             
  2930.         $aRet = array();
  2931.         $aTemp $this->getNativeQueryResults($sSql);
  2932.         if(count($aTemp) > 0
  2933.             $aRet $aTemp[0];        
  2934.                 
  2935.         return $aRet
  2936.     } 
  2937.     
  2938.     function getDefaultBibleTranslation($cbook_id$request)
  2939.     {        
  2940.         $sBibleStr '';
  2941.         $nBibleTransID $request->getSession()->get('current_bible_translation_id');
  2942.         if($nBibleTransID != '')
  2943.         {
  2944.                $sBibleStr '(case when t.id = ' $nBibleTransID ' then 1 else case when t.id = ' $this->DEFAULT_BIBLE_TRANSLATION_ID ' then 2 else case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 3 else 4 end end end)';
  2945.         }
  2946.         else
  2947.         {
  2948.             $locale $request->getLocale();             
  2949.             $sBibleStr "(case when t.language_id in (select id from language where shortcode = '" trim(str_replace("'""''"$locale)) . "') then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end)";
  2950.         }
  2951.     
  2952.         $sSql "select t.url, " $sBibleStr " as priority_order from bibletranslation t, biblebook b where b.canonicalization_id = " $cbook_id " and b.translation_id = t.id order by priority_order, t.languagedefault desc limit 1";
  2953.   //   echo $sSql."<br>";   
  2954.            $aRet = array();
  2955.         $aTemp $this->getNativeQueryResults($sSql);
  2956.         if(count($aTemp) > 0
  2957.             $aRet $aTemp[0];        
  2958.                 
  2959.         return $aRet
  2960.     } 
  2961.     
  2962.     function getNextReadingPlanStep($readingPlanUrl$stepOrder$request)
  2963.     {                
  2964.         $nUserID $request->getSession()->get("user_id");
  2965.         $sSql "select id from readingplan where url = " $this->dbstr($readingPlanUrl);    
  2966. // echo $sSql."<br>";
  2967.         $nReadingPlanID $this->getSingleData($sSql);
  2968.         
  2969.         $sSql "SELECT r.url as plan_url, rs.ordering as step_order"
  2970.                         ." FROM readingplan r, readingplanstep rs"
  2971.                         ." where r.id = " $nReadingPlanID
  2972.                         ." and r.id = rs.readingplan_id"                        
  2973.                         ." and rs.ordering > " $stepOrder
  2974.                         ." order by rs.ordering limit 1";
  2975.   //   echo $sSql."<br>";   
  2976.            $aRet = array();
  2977.         $aTemp $this->getNativeQueryResults($sSql);
  2978.         if(count($aTemp) > 0
  2979.             $aRet $aTemp[0];
  2980.         else
  2981.         {
  2982.             if(!empty($nUserID))
  2983.             {
  2984.                 // On the last step: check if there are any uncompleted steps
  2985.                 $sSql "select " $this->dbstr($readingPlanUrl) . " as plan_url, ordering as step_order from readingplanstep where readingplan_id = " $nReadingPlanID " and id not in (SELECT readingplanstep_id FROM user_readingplanstep urs, user_readingplan ur"
  2986.                     ." where ur.user_id = " $nUserID
  2987.                     ." and readingplan_id = " $nReadingPlanID " and ur.id = urs.user_readingplan_id) order by ordering";
  2988.      //   echo $sSql . "<br>";
  2989.                 $aTemp $this->getNativeQueryResults($sSql);
  2990.                 if(count($aTemp) > 0
  2991.                     $aRet $aTemp[0];
  2992.             }    
  2993.         }
  2994.         
  2995.         return $aRet;   
  2996.     } 
  2997.     
  2998.     function getPreviousReadingPlanStep($readingPlanUrl$stepOrder)
  2999.     {                
  3000.         $sSql "SELECT r.url as plan_url, rs.ordering as step_order"
  3001.                         ." FROM readingplan r, readingplanstep rs"
  3002.                         ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  3003.                         ." and r.id = rs.readingplan_id"                        
  3004.                         ." and rs.ordering < " $stepOrder
  3005.                         ." order by rs.ordering desc limit 1";
  3006.   //   echo $sSql."<br>";   
  3007.            $aRet = array();
  3008.         $aTemp $this->getNativeQueryResults($sSql);
  3009.         if(count($aTemp) > 0
  3010.             $aRet $aTemp[0];        
  3011.                 
  3012.         return $aRet;   
  3013.     }
  3014.     
  3015.     function getReadingPlanStepList($readingPlanUrl$bibleTranslationUrl)
  3016.     {
  3017.         $sSql "SELECT rs.ordering as step_order, b.name || ' ' || cc1.ordering || ':' || cv1.ordering || case when cc1.ordering <> cc2.ordering or cv1.ordering <> cv2.ordering then '-' else '' end || case when cc1.ordering <> cc2.ordering then cc2.ordering || ':' else '' end || case when cc1.ordering <> cc2.ordering or cv1.ordering <> cv2.ordering then cv2.ordering || '' else '' end as book_str FROM  readingplan r, readingplanstep rs, canonicalbibleverse cv1, canonicalbiblechapter cc1, canonicalbiblebook cb1, canonicalbibleverse cv2, canonicalbiblechapter cc2, biblebook b, bibletranslation bt" 
  3018.                 ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  3019.                 ." and bt.url = '" trim(str_replace("'""''"$bibleTranslationUrl)) . "'"
  3020.                 ." and r.id = rs.readingplan_id"                 
  3021.                  ." and cv1.id = rs.startverse_id and cv1.chapter_id = cc1.id"                                
  3022.                 ." and cb1.id = cc1.book_id"                
  3023.                 ." and cv2.id = rs.endverse_id and cv2.chapter_id = cc2.id"
  3024.                 ." and b.canonicalization_id = cb1.id and b.translation_id = bt.id"
  3025.                  ." order by rs.ordering";
  3026.  //  echo $sSql . "<br>";   
  3027.         $aRet $this->getNativeQueryResults($sSql);
  3028.         return $aRet
  3029.     } 
  3030.     
  3031.     function getStepCompletedPercentage($readingPlanUrl$request)
  3032.     {
  3033.         $nRet 0;
  3034.         $nUserID $request->getSession()->get("user_id");
  3035.         if(empty($nUserID))
  3036.         {
  3037.             return $nRet;
  3038.         }
  3039.         
  3040.         $sSql "SELECT CAST(count(distinct us.id) AS FLOAT) / CAST(count(rs.id) AS FLOAT) * 100 as completed_percentage" 
  3041.                 ." FROM readingplan r, readingplanstep rs left join (select urs.* from user_readingplanstep urs, user_readingplan ur where ur.user_id = " $nUserID " and ur.id = urs.user_readingplan_id) us on rs.id = us.readingplanstep_id"
  3042.                 ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  3043.                 ." and r.id = rs.readingplan_id";
  3044.  //  echo $sSql . "<br>";             
  3045.         $nRet 0;
  3046.         $aTemp $this->getNativeQueryResults($sSql);
  3047.         if(count($aTemp) > 0
  3048.             $nRet round(current($aTemp[0]));
  3049.                 
  3050.         return $nRet
  3051.     } 
  3052.     
  3053.     function getReadingPlanFirstStepOrder($readingPlanUrl)
  3054.     {
  3055.         $sSql "SELECT min(rs.ordering) as first_order"
  3056.                 ." FROM readingplan r, readingplanstep rs"
  3057.                 ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  3058.                 ." and r.id = rs.readingplan_id";
  3059.  //  echo $sSql . "<br>";             
  3060.         $nRet null;
  3061.         $aTemp $this->getNativeQueryResults($sSql);
  3062.         if(count($aTemp) > 0
  3063.             $nRet current($aTemp[0]);        
  3064.                 
  3065.         return $nRet
  3066.     }  
  3067.     
  3068.     function getReadingPlanOrderInfo($readingPlanUrl)
  3069.     {
  3070.         $sSql "SELECT min(rs.ordering) as first_order, max(rs.ordering) as last_order"
  3071.                 ." FROM readingplan r, readingplanstep rs"
  3072.                 ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  3073.                 ." and r.id = rs.readingplan_id";
  3074.    // echo $sSql . "<br>";    
  3075.         $aRet = array();
  3076.         $aTemp $this->getNativeQueryResults($sSql);
  3077.         if(count($aTemp) > 0
  3078.         {
  3079.             $aRet $aTemp[0];                   
  3080.         }
  3081.                 
  3082.         return $aRet;  
  3083.     }
  3084.     
  3085.     function IsReadingPlanStepCompleted($vStepID$request)
  3086.     {
  3087.         $nUserID $this->getCurrUserID($request);
  3088.         if(empty($nUserID))
  3089.         {
  3090.             return false;
  3091.         }
  3092.         $sSql "SELECT urs.id FROM user_readingplanstep urs, user_readingplan ur"
  3093.                 ." where ur.user_id = " $nUserID
  3094.                 ." and urs.readingplanstep_id = " $vStepID
  3095.                 ." and ur.id = urs.user_readingplan_id";
  3096. //    echo $sSql . "<br>";    
  3097.         $nID $this->getSingleData($sSql);                
  3098.         return (!empty($nID));  
  3099.     }
  3100.     
  3101.     function IsLastReadingPlanStepUncompleted($vStepID$request)
  3102.     {
  3103.         $bRet false;
  3104.         $nUserID $this->getCurrUserID($request);
  3105.         if(empty($nUserID))
  3106.         {
  3107.             return $bRet;
  3108.         }
  3109.         $sSql "select readingplan_id from readingplanstep where id = " $vStepID;    
  3110. // echo $sSql."<br>";
  3111.         $nReadingPlanID $this->getSingleData($sSql);
  3112.         
  3113.         $sSql "select id from readingplanstep where readingplan_id = " $nReadingPlanID " and id not in (SELECT urs.readingplanstep_id FROM user_readingplanstep urs, user_readingplan ur"
  3114.                 ." where ur.user_id = " $nUserID
  3115.                 ." and ur.readingplan_id = " $nReadingPlanID " and ur.id = urs.user_readingplan_id)";
  3116.  //   echo $sSql . "<br>";    
  3117.         $aData $this->getListData($sSql);
  3118.         $aID = array();
  3119.         foreach($aData as $d)
  3120.         {
  3121.             $aID[] = $d['id'];
  3122.         }
  3123.         if(count($aID) === && in_array($vStepID$aID))
  3124.         {
  3125.             $bRet true;
  3126.         }             
  3127.         return $bRet;  
  3128.     }    
  3129.     
  3130.     function getTranslationInfo($workUrl,$locale,$passageId)
  3131.     {       
  3132.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  3133.         
  3134.         $sSql "SELECT t.url as translation_url, d.url as division_url, d.ordering as division_order, p.ordering as passage_order,"
  3135.                 " case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  3136.                 ." FROM expositiontranslation t join expositionwork w on t.work_id = w.id" 
  3137.                 ." join expositiondivision d on d.work_id = w.id"   
  3138.                 ." join expositionpassage p on p.division_id = d.id" 
  3139.                 ." join expositiontranslationtext tt on tt.translation_id = t.id"    
  3140.                 ." join expositiontextunit tu on tt.placement_id = tu.id and tu.passage_id = p.id"            
  3141.                 ." WHERE w.url = '" trim(str_replace("'""''"$workUrl)) . "'";
  3142.                 
  3143.         if($passageId != null)
  3144.             $sSql .= " and p.id = " $passageId;     
  3145.                 
  3146.         $sSql .= " AND t.language_id = " $nLanguageID         
  3147.                 ." AND t.ispublic AND w.ispublic and t.url is not null and t.url <> ''" 
  3148.                 ." ORDER BY division_order, passage_order, lang_default_order limit 1";        
  3149.              
  3150.     //    echo $sSql . "<br>";          
  3151.         $aRet = array();
  3152.         $aTemp $this->getNativeQueryResults($sSql);
  3153.         if(count($aTemp) > 0
  3154.         {
  3155.             $aRet $aTemp[0];                   
  3156.         }
  3157.         
  3158.         if(empty($aRet))
  3159.         {
  3160.             $sLangStr '';
  3161.             if($nLanguageID != null)
  3162.             {
  3163.                 $sLangStr 'case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 1 else';    
  3164.                 $sLangStr .= ' 2 end';                    
  3165.                 $sLangStr .= ' as language_order';        
  3166.             }
  3167.             else
  3168.                 $sLangStr .= '1 as language_order';    
  3169.                  
  3170.             $sSql "SELECT t.url as translation_url, d.url as division_url, d.ordering as division_order, p.ordering as passage_order," $sLangStr 
  3171.                     ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  3172.                     ." FROM expositiontranslation t join expositionwork w on t.work_id = w.id" 
  3173.                     ." join expositiondivision d on d.work_id = w.id"   
  3174.                     ." join expositionpassage p on p.division_id = d.id" 
  3175.                     ." join expositiontranslationtext tt on tt.translation_id = t.id"    
  3176.                     ." join expositiontextunit tu on tt.placement_id = tu.id and tu.passage_id = p.id"            
  3177.                     ." WHERE w.url = '" trim(str_replace("'""''"$workUrl)) . "'"                
  3178.                     ." AND t.ispublic AND w.ispublic and t.url is not null and t.url <> ''" 
  3179.                     ." ORDER BY division_order, passage_order, language_order, lang_default_order limit 1";        
  3180.                  
  3181.         //    echo $sSql . "<br>";          
  3182.             $aRet = array();
  3183.             $aTemp $this->getNativeQueryResults($sSql);
  3184.             if(count($aTemp) > 0
  3185.             {
  3186.                 $aRet $aTemp[0];                   
  3187.             }
  3188.         }
  3189.                 
  3190.         return $aRet
  3191.     }     
  3192.     
  3193.     function getNextBookID($book_id$booklist)
  3194.     {                
  3195.         $nRet null;     
  3196.         $bHasBook false;       
  3197.         foreach($booklist as $book) {
  3198.             if($bHasBook)
  3199.             {
  3200.                 $nRet $book['id'];
  3201.                 break;
  3202.             }    
  3203.         
  3204.             if($book['id'] == $book_id)
  3205.                 $bHasBook true;
  3206.         }          
  3207.         return $nRet;   
  3208.     }  
  3209.     
  3210.     function getPreviousBookID($book_id$booklist)
  3211.     {                
  3212.         $nRet null;                   
  3213.         foreach($booklist as $book) {  
  3214.             if($book['id'] == $book_id)
  3215.             {                
  3216.                 break;
  3217.             }    
  3218.             $nRet $book['id']; 
  3219.         }          
  3220.         return $nRet;   
  3221.     }  
  3222.     
  3223.     function setCurrentUrl($request)
  3224.     {
  3225.         $sUrl $_SERVER['REQUEST_URI'];  
  3226.         $request->getSession()->set("current_page_url"$sUrl);
  3227.         $request->getSession()->set("from_login""");    
  3228.     }
  3229.     
  3230.     function getCurrentUrl($request)
  3231.     {
  3232.         $sUrl $request->getSession()->get('current_page_url');  
  3233.                         
  3234.         if(strpos($sUrl"exposition/translation") !== false)
  3235.          {     
  3236.             //$sUrl = trim($sUrl, "/"); 
  3237.         }
  3238.         
  3239.         // Fix the cache issue on bible chapter pages
  3240.         if(strpos($sUrl"bible/") !== false && strpos($sUrl"/stories/") === false && strpos($sUrl"/story/") === false)
  3241.          {
  3242.              if(strpos($sUrl"?/") !== false)
  3243.              {
  3244.                  $sUrl .= "&";
  3245.              }
  3246.              else
  3247.              {
  3248.                  $sUrl .= "?";
  3249.              }
  3250.              
  3251.              $sUrl .= date("YmdHis");
  3252.          }
  3253.              
  3254.         return $sUrl
  3255.     }
  3256.     
  3257.     function goToLoginPage($request)
  3258.     {     
  3259.         $request->getSession()->set("from_login"'1');
  3260.         return $this->renderView('login', array());
  3261.     } 
  3262.     
  3263.     function getCurrUserID($request)
  3264.     {
  3265.         return $request->getSession()->get('user_id'); 
  3266.     }    
  3267.         
  3268.     function getWorkPassageScanImageFileName($passage_id)
  3269.     {        
  3270.         $aRet = array();           
  3271.         $sSql "select distinct image_filename from passage_scanimage where passage_id=".$passage_id." order by image_filename";   
  3272.   //   echo $sSql."<br>";   
  3273.            $aRet $this->getNativeQueryResults($sSql);                
  3274.         return $aRet
  3275.     }
  3276.     
  3277.     function getPreviousPassageWithScan($passage_id)
  3278.     {
  3279.         $sSql "SELECT p.id"
  3280.                 ." FROM expositionpassage p, expositiondivision d, passage_scanimage ps"
  3281.                 ." WHERE d.work_id in (select d1.work_id from expositionpassage p1, expositiondivision d1 where p1.id = " $passage_id " and p1.division_id = d1.id) and p.division_id = d.id and p.ordering < (select p1.ordering from expositionpassage p1 where p1.id = " $passage_id ") and ps.passage_id = p.id and ps.image_filename not in (select image_filename from passage_scanimage where passage_id = " $passage_id ") and ps.section_num < 2 order by p.ordering desc limit 1";
  3282.      //          echo $sSql."<br>";
  3283.         $aRet = array();
  3284.         $aTemp $this->getNativeQueryResults($sSql);
  3285.         if(count($aTemp) > 0
  3286.             $aRet $aTemp[0];        
  3287.                 
  3288.         return $aRet;          
  3289.     }   
  3290.     
  3291.     function getNextPassageWithScan($passage_id)
  3292.     {
  3293.         $sSql "SELECT p.id"
  3294.                 ." FROM expositionpassage p, expositiondivision d, passage_scanimage ps"
  3295.                 ." WHERE d.work_id in (select d1.work_id from expositionpassage p1, expositiondivision d1 where p1.id = " $passage_id " and p1.division_id = d1.id) and p.division_id = d.id and p.ordering > (select p1.ordering from expositionpassage p1 where p1.id = " $passage_id ") and ps.passage_id = p.id and ps.image_filename not in (select image_filename from passage_scanimage where passage_id = " $passage_id ") and ps.section_num < 2 order by p.ordering limit 1";
  3296.       //         echo $sSql."<br>";
  3297.         $aRet = array();
  3298.         $aTemp $this->getNativeQueryResults($sSql);
  3299.         if(count($aTemp) > 0
  3300.             $aRet $aTemp[0];        
  3301.                 
  3302.         return $aRet;          
  3303.     } 
  3304.     
  3305.     function getCurrentPassageForLatin($passage_id)
  3306.     {
  3307.         $sSql "SELECT t.translatedtitle || ' ' || p.swedenborgsection as title"
  3308.                 ." FROM expositionpassage p, expositiondivision d, expositiontranslation t"
  3309.                 ." WHERE p.id = " $passage_id " and p.division_id = d.id and t.work_id = d.work_id and t.language_id = " $this->LANGUAGE_ID_LATIN " order by islanguagedefault desc limit 1";
  3310.      //          echo $sSql."<br>";
  3311.         $aRet = array();
  3312.         $aTemp $this->getNativeQueryResults($sSql);
  3313.         if(count($aTemp) > 0
  3314.             $aRet $aTemp[0];        
  3315.                 
  3316.         return $aRet;          
  3317.     } 
  3318.     
  3319.     function getCommentaryUrl($storyId$bibleTranslationUrl)
  3320.     {
  3321.         $sSql "SELECT t.url, case when l.language_id is not null then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end as lang_order"
  3322.                 ." FROM story_work sw, expositionwork w, expositiontranslation t"
  3323.                 ." left join (select language_id from bibletranslation where url='"trim(str_replace("'""''"$bibleTranslationUrl)) . "') as l on t.language_id = l.language_id"
  3324.                 ." WHERE sw.story_id = " $storyId " and t.work_id = sw.work_id and t.work_id = w.id and w.ispublic AND t.ispublic order by lang_order, sw.ordering, t.islanguagedefault desc limit 1";
  3325.           //     echo $sSql."<br>";
  3326.         $sRet '';
  3327.         $aTemp $this->getNativeQueryResults($sSql);
  3328.         if(count($aTemp) > 0
  3329.             $sRet current($aTemp[0]);        
  3330.                 
  3331.         return $sRet;          
  3332.     } 
  3333.     
  3334.     function getPublicCommentaryUrl($storyId$commentaryUrl)
  3335.     {
  3336.         $sSql "SELECT t.url"
  3337.                 ." FROM story_work sw, expositiontranslation t, expositionwork w"                
  3338.                 ." WHERE sw.story_id = " $storyId 
  3339.                 ." and t.url = '" trim(str_replace("'""''"$commentaryUrl)) . "'"
  3340.                 ." and t.work_id = sw.work_id and t.work_id = w.id and w.ispublic AND t.ispublic";
  3341.           //     echo $sSql."<br>";
  3342.         $sRet '';
  3343.         $aTemp $this->getNativeQueryResults($sSql);
  3344.         if(count($aTemp) > 0
  3345.             $sRet current($aTemp[0]);        
  3346.                 
  3347.         return $sRet;          
  3348.     } 
  3349.     
  3350.     function getFirstBibleTranslation($request)
  3351.     {           
  3352.         $locale $request->getLocale();     
  3353.         $cbook_id 1;
  3354.         $sBibleStr '';
  3355.         $nBibleTransID $request->getSession()->get('current_bible_translation_id');
  3356.         if($locale == 'en')
  3357.         {
  3358.             if($nBibleTransID != '')
  3359.             {
  3360.                    $sBibleStr "(case when t.id = " $nBibleTransID " then 1 else case when t.id = " $this->DEFAULT_BIBLE_TRANSLATION_ID " then 2 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3 else 4 end end end)";
  3361.             }
  3362.             else
  3363.             {
  3364.                 $sBibleStr "(case when t.id = " $this->DEFAULT_BIBLE_TRANSLATION_ID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end)";
  3365.             }
  3366.             
  3367.             $sSql "select t.id, t.url, t.name, cb.url as book_url, " $sBibleStr " as priority_order from bibletranslation t, biblebook b, canonicalbiblebook cb where b.canonicalization_id = " $cbook_id " and cb.id = b.canonicalization_id and b.translation_id = t.id order by priority_order, t.languagedefault desc limit 1";
  3368.         }
  3369.         else
  3370.         {
  3371.             if($nBibleTransID != '')
  3372.             {
  3373.                    $sBibleStr "(case when t.id = " $nBibleTransID " then 1 else case when l.shortcode = '" trim(str_replace("'""''"$locale)) . "' then 2 else case when t.id = " $this->DEFAULT_BIBLE_TRANSLATION_ID " then 3 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 4 else 5 end end end end)";
  3374.             }
  3375.             else
  3376.             {
  3377.                 $sBibleStr "(case when l.shortcode = '" trim(str_replace("'""''"$locale)) . "' then 1 else case when t.id = " $this->DEFAULT_BIBLE_TRANSLATION_ID " then 2 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3 else 4 end end end)";
  3378.             }
  3379.             
  3380.             $sSql "select t.id, t.url, t.name, cb.url as book_url, " $sBibleStr " as priority_order from bibletranslation t, biblebook b, canonicalbiblebook cb, language l where b.canonicalization_id = " $cbook_id " and cb.id = b.canonicalization_id and b.translation_id = t.id and t.language_id = l.id order by priority_order, t.languagedefault desc limit 1";
  3381.         }    
  3382.         
  3383.    //  echo $sSql."<br>";   
  3384.            $aRet = array();
  3385.         $aTemp $this->getNativeQueryResults($sSql);
  3386.         if(count($aTemp) > 0
  3387.             $aRet $aTemp[0];        
  3388.                 
  3389.         return $aRet;    
  3390.     }           
  3391.     
  3392.     function getWorkRefForWork($passage_id$translation_id$language_id$bCheck=false)
  3393.     {               
  3394.         $aRet = array();
  3395.         if(empty($passage_id))
  3396.             return $aRet;
  3397.              
  3398.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English  
  3399.                   
  3400.         $sFilter ' p.id in (';
  3401.               
  3402.           $sFilter .= 'select ps.id
  3403. FROM refexposition re, textunit_combinedreference tc, expositiontextunit ts, expositiontextunit t1, expositiontextunit t2, expositionpassage ps, expositiondivision d1, expositiondivision da, expositionpassage p1, expositionpassage p2, expositionpassage pa'
  3404.                 .' WHERE ts.passage_id = ps.id and ts.id = tc.textunit_id and re.container_id = tc.combinedreference_id and t1.id = re.startlocation_id and t2.id = re.endlocation_id and t1.passage_id = p1.id and t2.passage_id = p2.id and p1.division_id = d1.id and pa.id = ' $passage_id ' and pa.division_id = da.id and da.work_id = d1.work_id and pa.ordering >= p1.ordering and pa.ordering <= p2.ordering) and w.swedenborgtype ';
  3405.               
  3406.         $sFilter .= ' is not null'
  3407.                     
  3408.          $sSql1 "select array_to_string(array_agg(DISTINCT id), ',') from (SELECT distinct on (w.id) t.id" 
  3409.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  3410.                 ." WHERE " $sFilter;    
  3411.         $sSql1 .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id in ( ".$language_id"," $nDefaultLanguageID ") and t.ispublic and w.ispublic and t.url is not null and t.url <> ''";
  3412.         $sSql1 .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  3413.         $sSql1 .= " order by w.id, ";
  3414.         
  3415.         $sSql1 .= " (case when t.id = " $translation_id " then 1 else 2 end),";
  3416.         
  3417.         if($language_id != $nDefaultLanguageID)
  3418.         {
  3419.             $sSql1 .= " (case when t.language_id = " $language_id " then 1 else 2 end), ";
  3420.         }
  3421.         
  3422.         $sSql1 .= " t.islanguagedefault desc";
  3423.         
  3424.         if($bCheck)
  3425.               $sSql1 .= " limit 1";
  3426.         
  3427.         $sSql1 .= " ) as t";
  3428.   //    echo $sSql1."<br>";  
  3429.         $aTrans $this->getNativeQueryResults($sSql1);         
  3430.         $sTransIDs '';
  3431.         if(count($aTrans) > 0)                      
  3432.             $sTransIDs implode(''$aTrans[0]);
  3433.             
  3434.         $bHasTrans = (!empty($sTransIDs));    
  3435.         
  3436.         $sSql "";
  3437.         if($bHasTrans
  3438.         {                 
  3439.             $sSql "SELECT distinct on (p.id) p.id, w.swedenborgtype, t.translatedtitle AS title, (case when p.swedenborgsection is not null then p.swedenborgsection else cast(p.ordering as text) end) as num, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as link_spec, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering, case when t.language_id = " $language_id " then 1 else 2 end as lang_order"
  3440.                     ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  3441.                     ." WHERE " $sFilter;          
  3442.               $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id";
  3443.               $sSql .= " and t.id in (" $sTransIDs ")";             
  3444.               $sSql .= " order by p.id, lang_order"
  3445.                                                 
  3446.               $sSql "select * from (" $sSql ") as t2 order by work_order, title, ordering";
  3447.    //  echo $sSql."<br>";
  3448.                $aRet $this->getNativeQueryResults($sSql);  
  3449.                  
  3450.          }           
  3451.           
  3452.            return $aRet;
  3453.     }
  3454.     
  3455.     function getGCEDRefForWork($passage_id$bCheck=false)
  3456.     {  
  3457.         if(empty($passage_id))
  3458.             return array();
  3459.                                        
  3460.         $sSql $this->getGCEDSqlSelectStr();
  3461.         $sSql .= " FROM resource_workref rw, resource r left join resourcetype rt on r.resourcetype_id = rt.id";
  3462.         $sSql .= " WHERE rw.passage_id = " $passage_id " and r.id = rw.resource_id and r.publicfile is not null";
  3463.         $sSql .= " and r.publish order by r.title";
  3464.         
  3465.         if($bCheck)
  3466.               $sSql .= " limit 1";
  3467.               
  3468.     // echo $sSql."<br>";
  3469.            return $this->getNativeQueryResults($sSql);  
  3470.     }
  3471.     
  3472.     function getGCEDRefForBible($aVerseInfo$bChapter$bCheck=false)
  3473.     {               
  3474.         if(empty($aVerseInfo))
  3475.             return array();
  3476.                    
  3477.         $aChapter = array();
  3478.         $sVerseCChapterIDs $aVerseInfo['CChapterIDs'];        
  3479.  /*       foreach($verses as $verse) {
  3480.             if($verse === null) {
  3481.                 continue;
  3482.             }
  3483.             
  3484.             foreach($verse->getCanonicalization() as $canonicalVerse) {
  3485.                 if($canonicalVerse != null) 
  3486.                 {                     
  3487.                     $aChapter[] = $canonicalVerse->getChapter()->getId();
  3488.                 }
  3489.             }                       
  3490.         } 
  3491.                 
  3492.         foreach($chapters as $chapter) {
  3493.             if($chapter === null) {
  3494.                 continue;
  3495.             }
  3496.             $canonicalChapter = $chapter->getCanonicalization();
  3497.             if($canonicalChapter != null) 
  3498.             {                              
  3499.                 $aChapter[] = $canonicalChapter->getId();                   
  3500.             }
  3501.         }*/
  3502.         
  3503.         $sChapters '';
  3504.         if($bChapter)
  3505.             $sChapters $aVerseInfo['CChapterIDs']; 
  3506.         
  3507.         $aRet = array();
  3508.         
  3509.      //   $aChapter = array_unique($aChapter);
  3510.     //    $sChapters = implode (',', $aChapter);
  3511.         if($sChapters != '' && $sVerseCChapterIDs != '')
  3512.             $sChapters .= ','.$sVerseCChapterIDs;
  3513.         else if($sVerseCChapterIDs != '')
  3514.             $sChapters $sVerseCChapterIDs;
  3515.         
  3516.         if(!empty($sChapters))
  3517.         {            
  3518.             $sSql $this->getGCEDSqlSelectStr();
  3519.             $sSql .= " FROM resource_bibleref rb, resource r left join resourcetype rt on r.resourcetype_id = rt.id";
  3520.             $sSql .= " WHERE rb.chapter_id in (" $sChapters ") and r.id = rb.resource_id and r.publicfile is not null";
  3521.             $sSql .= " and r.publish order by r.title";
  3522.             
  3523.             if($bCheck)
  3524.                   $sSql .= " limit 1";
  3525.               
  3526.      //    echo $sSql."<br>";
  3527.              $aRet $this->getNativeQueryResults($sSql);
  3528.          }
  3529.          
  3530.            return $aRet;  
  3531.     }
  3532.     
  3533.     function getGCEDSqlSelectStr()
  3534.     {                       
  3535.         $sSql "SELECT distinct r.publicfile, r.title, r.searchsummary,";
  3536.         $sSql .= " case when rt.description is null then '' else rt.description || ' | ' end";
  3537.         $sSql .= " || case when r.minaudienceage is null and r.maxaudienceage is null then 'All Ages ' else";
  3538.         $sSql .= " case when r.minaudienceage is not null or r.maxaudienceage is not null then 'Ages ' else '' end end";
  3539.         $sSql .= " || case when r.minaudienceage is null and r.maxaudienceage is not null then 'up to ' else";
  3540.         $sSql .= " case when r.minaudienceage is not null and r.maxaudienceage is null then 'over ' else '' end end";
  3541.         $sSql .= " || case when r.minaudienceage is null then '' else r.minaudienceage || '' end";
  3542.         $sSql .= " || case when r.minaudienceage is not null and r.maxaudienceage is not null then ' - ' else '' end";
  3543.         $sSql .= " || case when r.maxaudienceage is null then '' else '' || r.maxaudienceage end";
  3544.         $sSql .= " as otherinfo";
  3545.            return $sSql;  
  3546.     }
  3547.     
  3548.     function getRelatedPassages($passage_id$language_id$bCheck=false)
  3549.     {               
  3550.         if(empty($passage_id))
  3551.             return array();
  3552.                  
  3553.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English    
  3554.                     
  3555.         $sFilter ' p.id in (';              
  3556.           $sFilter .= 'select distinct passage_id2 from relatedpassage WHERE passage_id1 = ' $passage_id
  3557.                 .' union select distinct passage_id1 from relatedpassage WHERE passage_id2 = ' $passage_id ')';
  3558.                                    
  3559.         $sSql "select * from (SELECT distinct on (p.id) p.id, w.swedenborgtype, t.translatedtitle AS title, (case when p.swedenborgsection is not null then p.swedenborgsection else cast(p.ordering as text) end) as num, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as link_spec, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering, case when t.language_id = " $language_id " then 1 else 2 end as lang_order"
  3560.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  3561.                 ." WHERE " $sFilter;          
  3562.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (";
  3563.           
  3564.           $sSql .= "SELECT distinct on (w.id) t.id"
  3565.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  3566.                 ." WHERE " $sFilter;          
  3567.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (";
  3568.           
  3569.           $sSql .= "SELECT distinct on (w.id) t.id"
  3570.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  3571.                 ." WHERE " $sFilter;          
  3572.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id in ( ".$language_id"," $nDefaultLanguageID ") and t.ispublic and w.ispublic and t.url is not null and t.url <> ''";
  3573.           $sSql .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  3574.           $sSql .= " order by w.id, t.islanguagedefault desc)) order by p.id, lang_order"
  3575.           
  3576.           if($bCheck)
  3577.               $sSql .= " limit 1";
  3578.                         
  3579.           $sSql .= ") as t2 order by work_order, title, ordering";
  3580.   //   echo $sSql."<br>";
  3581.            return $this->getNativeQueryResults($sSql);  
  3582.     }
  3583.     
  3584.     function getVerseCrossRefs($aVerseInfo$request$bCheck=false)
  3585.     {        
  3586.         if(empty($aVerseInfo))
  3587.             return array();
  3588.     
  3589.         $language_id $aVerseInfo['LanguageID'];
  3590.         $translation_id $aVerseInfo['TranslationID'];
  3591.         $sCVerseIDs $aVerseInfo['CVerseIDs'];
  3592.         
  3593.         if($sCVerseIDs == ''
  3594.             return array();
  3595.         
  3596.         if($language_id == '')
  3597.             $language_id $this->LANGUAGE_ID_ENGLISH;
  3598.             
  3599.         $sFilter1 '(';
  3600.         $sFilter1 .= 'select distinct canonicalbibleverse_id1 as cvid from bibleversecross where canonicalbibleverse_id2 in (' $sCVerseIDs ')';                   
  3601.         $sFilter1 .= ')';    
  3602.         
  3603.         $sFilter2 '(';
  3604.         $sFilter2 .= 'select distinct canonicalbibleverse_id2 as cvid from bibleversecross where canonicalbibleverse_id1 in (' $sCVerseIDs ')';            
  3605.         $sFilter2 .= ')';
  3606.     
  3607.         $sBibleStr '(';
  3608.     /*    $nBibleTransID = $request->getSession()->get('current_bible_translation_id');
  3609.         if($nBibleTransID != '')        
  3610.             $sBibleStr .= 'case when trans.id = ' . $nBibleTransID . ' then 1 else '; */
  3611.                         
  3612.         if($translation_id != '')        
  3613.             $sBibleStr .= 'case when trans.id = ' $translation_id ' then 2 else ';    
  3614.             
  3615.         if($language_id != '')        
  3616.             $sBibleStr .= 'case when trans.language_id = ' $language_id ' then 3 else ';        
  3617.         
  3618.         if($language_id != $this->LANGUAGE_ID_ENGLISH)          
  3619.             $sBibleStr .= 'case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 4 else ';
  3620.         
  3621.         $sBibleStr .= ' 5 ';
  3622.         
  3623.         if($language_id != $this->LANGUAGE_ID_ENGLISH
  3624.             $sBibleStr .= ' end ';
  3625.         
  3626.     //    if($nBibleTransID != '')        
  3627.     //        $sBibleStr .= ' end';
  3628.             
  3629.         if($translation_id != ''
  3630.             $sBibleStr .= ' end';    
  3631.             
  3632.         if($language_id != '')        
  3633.             $sBibleStr .= ' end';    
  3634.         
  3635.         $sBibleStr .= ')';
  3636.              
  3637.         $sSql "select t.*, v2.id as ref_vid, b2.name as ref_book, c2.ordering as ref_chapternum, v2.indexdisplay as ref_versenum from (";
  3638.         
  3639.         $sSql .= "select * from (SELECT distinct on (cv.id, cf.canonicalbibleverse_id2) b.name as book_name, cc.ordering as chapter_num, cv.ordering as verse_num, cc.book_id, '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc.ordering || '_' || cv.ordering as ref_column_spec, " $sBibleStr " as priority_order, trans.url as translation_url, cb.url as book_url, v.content as verse_text, cf.canonicalbibleverse_id2 as refcvid"
  3640.                 ." FROM canonicalbibleverse cv, canonicalbiblechapter cc, canonicalbiblebook cb, (select * from canonicalbibleverse_bibleverse where canonicalbibleverse_id in (" $sFilter1 ")) as cbb, (select canonicalbibleverse_id1, canonicalbibleverse_id2 from bibleversecross where canonicalbibleverse_id2 in (" $sCVerseIDs ")) as cf, bibleverse v, biblechapter c, biblebook b, bibletranslation trans"
  3641.                 ." WHERE cv.id = cbb.canonicalbibleverse_id and cv.chapter_id = cc.id and cc.book_id = cb.id and v.id = cbb.bibleverse_id and v.chapter_id = c.id and c.book_id = b.id and cc.ordering=c.ordering and b.translation_id = trans.id and trans.enabled and cf.canonicalbibleverse_id1 = cv.id order by cv.id, cf.canonicalbibleverse_id2, priority_order asc, trans.languagedefault desc) as t1";
  3642.         
  3643.         $sSql .= " union ";
  3644.         $sSql .= "select * from (SELECT distinct on (cv.id, cf.canonicalbibleverse_id1) b.name as book_name, cc.ordering as chapter_num, cv.ordering as verse_num, cc.book_id, '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc.ordering || '_' || cv.ordering as ref_column_spec, " $sBibleStr " as priority_order, trans.url as translation_url, cb.url as book_url, v.content as verse_text, cf.canonicalbibleverse_id1 as refcvid"
  3645.             ." FROM canonicalbibleverse cv, canonicalbiblechapter cc, canonicalbiblebook cb, (select * from canonicalbibleverse_bibleverse where canonicalbibleverse_id in (" $sFilter2 ")) as cbb, (select canonicalbibleverse_id1, canonicalbibleverse_id2 from bibleversecross where canonicalbibleverse_id1 in (" $sCVerseIDs ")) as cf, bibleverse v, biblechapter c, biblebook b, bibletranslation trans"
  3646.             ." WHERE cv.id = cbb.canonicalbibleverse_id and cv.chapter_id = cc.id and cc.book_id = cb.id and v.id = cbb.bibleverse_id and v.chapter_id = c.id and c.book_id = b.id and cc.ordering=c.ordering and b.translation_id = trans.id and trans.enabled and cf.canonicalbibleverse_id2 = cv.id order by cv.id, cf.canonicalbibleverse_id1, priority_order asc, trans.languagedefault desc) as t2";
  3647.         
  3648.         if($bCheck)
  3649.               $sSql .= " limit 1";
  3650.                 
  3651.         $sSql .= ") as t, (select * from canonicalbibleverse_bibleverse where canonicalbibleverse_id in (" $sCVerseIDs ")) as cbb2, bibleverse v2, biblechapter c2, biblebook b2 where t.refcvid = cbb2.canonicalbibleverse_id and v2.id = cbb2.bibleverse_id and v2.chapter_id = c2.id and c2.book_id = b2.id and b2.translation_id = " $translation_id
  3652.                ." order by b2.id, c2.ordering, v2.ordering, book_id, chapter_num, verse_num";
  3653.     //  echo $sSql."<br>";
  3654.         return $this->getNativeQueryResults($sSql);         
  3655.     }
  3656.     
  3657.     function getBibleWordExplanations($aVerseInfo$request$row_num 0$bCheck=false)
  3658.     {            
  3659.         if(empty($aVerseInfo))
  3660.             return array();
  3661.         
  3662.         $canon = array();
  3663.         $nulls = array();       
  3664.         $verseLanguage $aVerseInfo['LanguageID'];
  3665.         $sCVerseIDs $aVerseInfo['CVerseIDs'];
  3666.         $sVerseIDs $aVerseInfo['VerseIDs'];
  3667.         
  3668.         if($verseLanguage == '')
  3669.             $verseLanguage $this->LANGUAGE_ID_ENGLISH;
  3670.                   
  3671.         if($sCVerseIDs == '') {
  3672.             return null;
  3673.         } 
  3674.         
  3675.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH;    
  3676.         
  3677.         $sTransIDs $this->getExplanationTransIDs($sVerseIDs$verseLanguage$nDefaultLanguageID); 
  3678.         if(empty($sTransIDs))
  3679.             return array();
  3680.             
  3681.         $sBorderStr $this->getBoundaryStrForSql($verseLanguage);
  3682.                                  
  3683.         $sTermTable "(select * from (SELECT distinct on (lower(t.text)) cl.explanation_id, t.id as term_id, t.text as term_text, bv.ordering, POSITION(lower(t.text) in lower(bv.content)) as term_order, vc.concept_id"
  3684.             ." FROM verse_concept vc, term_concept tc, term t, (select cl1.*, trans1.id as explanation_id from concept_work cl1, expositiontranslation trans1 where trans1.id in (" $sTransIDs ") and cl1.work_id = trans1.work_id) as cl, (select * from canonicalbibleverse_bibleverse where bibleverse_id in (" $sVerseIDs ")) as cbb, bibleverse bv"
  3685.             ." WHERE cbb.canonicalbibleverse_id = vc.verse_id and tc.concept_id = vc.concept_id and t.id = tc.term_id and cl.concept_id = tc.concept_id and t.language_id = " $verseLanguage;
  3686.         $sTermTable .= " and cbb.bibleverse_id = bv.id and case when t.text is not null and (bv.content ~* ('" $sBorderStr "' || " $this->EscapeTextForRegex("t.text") . " || '" $sBorderStr "')) then true else false end order by lower(t.text), bv.ordering, t.id, cbb.bibleverse_id desc) as t1 order by ordering) as t2"
  3687.         
  3688.        // $sFilter = " t.id in (" . $sTransIDs . ")";
  3689.         
  3690.         $sTransTable " (SELECT tt.translation_id, string_agg(tt.text, ' ' order by tu.ordering) as text FROM (select * from expositiontranslationtext where translation_id in (" $sTransIDs ")) as tt, expositiontextunit tu where tt.placement_id = tu.id group by tt.translation_id) as trans";   
  3691.         
  3692.         $sSql "select * from (SELECT distinct on (p.id, t2.term_id) p.id, t2.term_text, trans.text as trans_text, t2.term_order, array_to_string((regexp_split_to_array(trans.text, '\s+'))[1:25], ' ') as trans_excerpt, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as ref_column_spec, t.url as translation_url, d.url as division_url, t2.ordering as verse_order, p.ordering, t2.concept_id, t2.term_id, t.work_id"
  3693.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d, " $sTermTable ", " $sTransTable
  3694.                 ." WHERE trans.translation_id = t.id and t.id = t2.explanation_id and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and w.ispublic AND t.ispublic";
  3695.                 
  3696.           if($bCheck)
  3697.                   $sSql .= " limit 1";      
  3698.                                   
  3699.           $sSql .= ") as t3 order by verse_order, term_order";
  3700.  //    echo $sSql."<br>";
  3701.          $aRet $this->getNativeQueryResults($sSql);
  3702.          
  3703.          $this->setWordExplanationSession($aRet$request$row_num);
  3704.  
  3705.            return $aRet
  3706.     } 
  3707.     
  3708.     function getBiblioForTranslation($translation_id)
  3709.     {        
  3710.         $sSql "SELECT credit, sourcelink from bibliographicdata b, translation_bibliographicdata tb"
  3711.                 ." WHERE tb.translation_id = ".$translation_id " and tb.bibliographicdata_id = b.id and sourcelink is not null and credit is not null";
  3712.  //    echo $sSql."<br>";
  3713.         $aRet $this->getNativeQueryResults($sSql);
  3714.         if(count($aRet) > 0)
  3715.             $aRet $aRet[0];        
  3716.                 
  3717.         return $aRet;
  3718.     } 
  3719.     
  3720.     function isOnMobile()
  3721.     {
  3722.         $bRet false;
  3723.         $useragent=@$_SERVER['HTTP_USER_AGENT'];
  3724.         if(preg_match('/mobile|android|iPad|(bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent))
  3725.         {
  3726.             $bRet true;
  3727.         }
  3728.                 
  3729.         return $bRet;
  3730.     }
  3731.     
  3732.     function isIPad()
  3733.     {
  3734.         $bRet false;
  3735.         $useragent=@$_SERVER['HTTP_USER_AGENT'];
  3736.         if(preg_match('/iPad/i',$useragent))
  3737.         {
  3738.             $bRet true;
  3739.         }
  3740.                 
  3741.         return $bRet;
  3742.     }
  3743.     
  3744.     function checkIfOnMobile($request)
  3745.     {
  3746.         $request->getSession()->set('is_on_mobile'$this->isOnMobile());
  3747.         
  3748.     }
  3749.     
  3750.     function OnMobile($request)
  3751.     {
  3752.         return $request->getSession()->get('is_on_mobile');
  3753.     }
  3754.     
  3755.     function setWordExplanationSession($aWordExplanation$request$row_num)
  3756.     {
  3757.         $aPrev = array();
  3758.         $aNext = array();
  3759.         $sPrev "";
  3760.         $nPrevWorkID "";
  3761.    // print_r($aWordExplanation);           
  3762.            $aTempWork = array();    
  3763.         foreach ($aWordExplanation as $wep)
  3764.         {
  3765.             $sTransUrl $wep['translation_url'];
  3766.             $nWorkID $wep['work_id'];
  3767.             if(!in_array($nWorkID$aTempWork))
  3768.             {
  3769.                 $aTempWork[] = $nWorkID;
  3770.                 if($sPrev != '')
  3771.                 {
  3772.                     $aPrev[$nWorkID] = $this->MULTI_URL_INDICATOR_EXPLANATION '_' $sPrev;
  3773.                     $aNext[$nPrevWorkID] = $this->MULTI_URL_INDICATOR_EXPLANATION '_' $sTransUrl;
  3774.                 }
  3775.                 
  3776.                 $sPrev $sTransUrl;
  3777.                 $nPrevWorkID $nWorkID;
  3778.             }
  3779.         }
  3780.     
  3781.         if($row_num 1)
  3782.         {
  3783.             $request->getSession()->set("prev_word_explanation".$row_num$aPrev);
  3784.             $request->getSession()->set("next_word_explanation".$row_num$aNext);
  3785.         }
  3786.         else
  3787.         {
  3788.             $request->getSession()->set("prev_word_explanation"$aPrev);
  3789.             $request->getSession()->set("next_word_explanation"$aNext);
  3790.         }
  3791.     }
  3792.     
  3793.     function getVerseInfo($verses)
  3794.     {    
  3795.         $aRet = array();
  3796.         $sVerseIDs '';
  3797.         $sCVerseIDs '';
  3798.         $verseLanguage '';
  3799.         $translation_id '';
  3800.         $book_id '';
  3801.         $nChapterID '';
  3802.         $sCChapterIDs '';
  3803.      //   $aChapter = array();
  3804.         $nChapterIndex '';
  3805.         foreach($verses as $verse) {
  3806.             if($verse === null) {
  3807.                 continue;
  3808.             }
  3809.             
  3810.             $nVerseID $verse->getId();
  3811.             
  3812.             if($sVerseIDs != '')
  3813.                 $sVerseIDs .= ',';
  3814.             
  3815.             $sVerseIDs .= $nVerseID;
  3816.                         
  3817.    /*         foreach($verse->getCanonicalization() as $canonicalVerse) {
  3818.                 if($canonicalVerse != null) 
  3819.                 {                
  3820.                     if($sCVerseIDs != '')
  3821.                         $sCVerseIDs .= ',';
  3822.                   
  3823.                     $sCVerseIDs .= $canonicalVerse->getId();
  3824.                     $chapter = $canonicalVerse->getChapter();
  3825.                     $aChapter[] = $chapter->getId();
  3826.                     if($nChapterIndex == '')
  3827.                         $nChapterIndex = $chapter->getOrdering();
  3828.                 }
  3829.             } */
  3830.              
  3831.             if($verseLanguage == '')
  3832.             {
  3833.                 $aVerseData $this->getVerseData($nVerseID);
  3834.                 $verseLanguage $aVerseData['language_id'];
  3835.                 $translation_id $aVerseData['translation_id'];
  3836.                 $book_id $aVerseData['book_id'];
  3837.                 $nChapterID $aVerseData['chapter_id'];
  3838.             }        
  3839.         }
  3840.         
  3841.         if(empty($sVerseIDs))
  3842.             return $aRet;
  3843.                       
  3844.         $aCVerse $this->getCVerseInfo($sVerseIDs);
  3845.         if(!empty($aCVerse))
  3846.         {
  3847.             $sCVerseIDs $aCVerse['cverse_ids'];
  3848.             $sCChapterIDs $aCVerse['cchapter_ids'];
  3849.             $nChapterIndex $aCVerse['first_chapter_index'];
  3850.         }
  3851.     
  3852.         $aRet['VerseIDs'] = $sVerseIDs;
  3853.         $aRet['CVerseIDs'] = $sCVerseIDs;
  3854.         $aRet['LanguageID'] = $verseLanguage;
  3855.       //  $aChapter = array_unique($aChapter);
  3856.        // $sCChapterIDs = implode (',', $aChapter);        
  3857.         $aRet['CChapterIDs'] = $sCChapterIDs;
  3858.         $aRet['TranslationID'] = $translation_id;
  3859.         $aRet['BookID'] = $book_id;
  3860.         $aRet['FirstChapterIndex'] = $nChapterIndex;
  3861.         $aRet['FirstChapterID'] = $nChapterID;
  3862.         
  3863.         return $aRet;
  3864.     } 
  3865.     
  3866.     function getExplainChapterTranslation($vCChapterID$vUserID$vTranslationUrl)
  3867.     {        
  3868.         $nRet = -1;
  3869.         if($vUserID != '')
  3870.         {
  3871.             $sSql "select \"UserLevelID\" from \"user\" where \"UserID\" = " $vUserID " and \"UserLevelID\" in (-1, 1, 2, 3, 5, 6)";    
  3872.     //     echo $sSql."<br>";                
  3873.             $aTemp $this->getNativeQueryResults($sSql);          
  3874.             if(count($aTemp) <= 0)
  3875.                 return -1;
  3876.             else
  3877.                 $nUserLevelID current($aTemp[0]);    
  3878.         
  3879.             $sFilter "";            
  3880.             if($nUserLevelID == $this->USER_LEVEL_ID_EXPLANATION_AUTHOR)
  3881.                 $sFilter .= " and (user_id = " $vUserID " or user_id is null)";    
  3882.         
  3883.             $sSql "select translation_id, case when language_id in (select language_id from bibletranslation where url = '" $vTranslationUrl "') then 1 else case when language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end as lang_order from vchapterexplanationforchecking where id = " $vCChapterID $sFilter " order by lang_order limit 1";    
  3884.     //     echo $sSql."<br>";    
  3885.             $aTemp $this->getNativeQueryResults($sSql);             
  3886.             if(count($aTemp) > 0)
  3887.             {                                    
  3888.                 $nRet $aTemp[0]['translation_id'];                    
  3889.             }
  3890.         }
  3891.         return $nRet;
  3892.     }
  3893.     
  3894.     function getExplanationTransIDs($sVerseIDs$verseLanguage$nDefaultLanguageID)
  3895.     {
  3896.         $sRet '';
  3897.         
  3898.         $sBorderStr $this->getBoundaryStrForSql($verseLanguage);
  3899.         
  3900.         $sSql "SELECT array_to_string(array_agg(distinct trans.id), ',') as trans_ids, array_to_string(array_agg(distinct t.id), ',') as term_ids "
  3901.             ." FROM verse_concept vc, term_concept tc, term t, concept_work cl, (select * from canonicalbibleverse_bibleverse where bibleverse_id in (" $sVerseIDs ")) as cbb, bibleverse bv, expositiontranslation trans"
  3902.             ." WHERE cbb.canonicalbibleverse_id = vc.verse_id and tc.concept_id = vc.concept_id and t.id = tc.term_id and cl.concept_id = tc.concept_id and t.language_id = " $verseLanguage;
  3903.         $sSql .= " and cl.work_id = trans.work_id and trans.language_id = t.language_id and cbb.bibleverse_id = bv.id and case when t.text is not null and (bv.content ~* ('" $sBorderStr "' || " $this->EscapeTextForRegex("t.text") . " || '" $sBorderStr "')) then true else false end";
  3904.  //    echo $sSql."<br>";
  3905.         $aTemp $this->getNativeQueryResults($sSql);                
  3906.         $sTransIDs1 '';    
  3907.         $sTermIDs1 '';            
  3908.         if(count($aTemp) > 0
  3909.         {            
  3910.             $sTransIDs1 $aTemp[0]['trans_ids'];
  3911.             $sTermIDs1 $aTemp[0]['term_ids'];
  3912.         }
  3913.         
  3914.         if($verseLanguage == $nDefaultLanguageID)
  3915.         {
  3916.             $sRet $sTransIDs1;
  3917.         }
  3918.         else
  3919.         {                    
  3920.             $sSql "SELECT array_to_string(array_agg(distinct trans.id), ',')"
  3921.             ." FROM verse_concept vc, term_concept tc, term t, concept_work cl, (select * from canonicalbibleverse_bibleverse where bibleverse_id in (" $sVerseIDs ")) as cbb, bibleverse bv, expositiontranslation trans"
  3922.                 ." WHERE cbb.canonicalbibleverse_id = vc.verse_id and tc.concept_id = vc.concept_id and t.id = tc.term_id and cl.concept_id = tc.concept_id and t.language_id = " $verseLanguage;
  3923.             $sSql .= " and cl.work_id = trans.work_id and cbb.bibleverse_id = bv.id and case when t.text is not null and (bv.content ~* ('" $sBorderStr "' || " $this->EscapeTextForRegex("t.text") . " || '" $sBorderStr "')) then true else false end";
  3924.             
  3925.             if($sTermIDs1 != '')
  3926.                 $sSql .= " and t.id not in (" $sTermIDs1 ")";
  3927.      //    echo $sSql."<br>";
  3928.             $aTemp $this->getNativeQueryResults($sSql);                
  3929.             $sTransIDs2 '';                
  3930.             if(count($aTemp) > 0
  3931.             {            
  3932.                 $sTransIDs2 implode(","$aTemp[0]);
  3933.             }
  3934.             
  3935.             if($sTransIDs1 != '' && $sTransIDs2 != '')
  3936.                 $sRet $sTransIDs1 ',' $sTransIDs2;
  3937.             else
  3938.             {
  3939.                 if($sTransIDs1 != '')
  3940.                     $sRet $sTransIDs1;
  3941.                 else if($sTransIDs2 != '')
  3942.                     $sRet $sTransIDs2;                    
  3943.             }         
  3944.         }
  3945.         
  3946.         return $sRet;
  3947.     }
  3948.     
  3949.     function getVerseContentWithConceptLinksForAllTrans($CVerseIDs)
  3950.     {  
  3951.         $aRet = array();        
  3952.         $aTranslation $this->getTranslationsForVerse($CVerseIDs);
  3953.         foreach($aTranslation as $trans
  3954.         {
  3955.             $nTransID $trans['id'];
  3956.             $nVerseID $trans['verse_id'];      
  3957.              $verses $this->bibleData('Verse')->findBy(array('id' => $nVerseID));      
  3958.             $aRet[$nTransID]['verse'] = current($verses);
  3959.       //      $aRet[$nTransID]['verse_concept'] = $verse_concept;
  3960.         }
  3961.     
  3962.         return $aRet;
  3963.     }
  3964.     
  3965.     function getTranslationsForVerse($CVerseIDs)
  3966.     {
  3967.         $aRet = array();
  3968.         
  3969.         $sSql "SELECT bt.id, v.id as verse_id from bibleverse v, canonicalbibleverse cv, (select * from canonicalbibleverse_bibleverse where canonicalbibleverse_id in (" $CVerseIDs ")) as cbb, bibletranslation bt, biblechapter c, biblebook b"
  3970.                 ." WHERE cv.id = cbb.canonicalbibleverse_id and v.id = cbb.bibleverse_id and v.chapter_id = c.id and b.id = c.book_id and b.translation_id=bt.id";
  3971.   //  echo $sSql."<br>";
  3972.         $aRet $this->getNativeQueryResults($sSql);            
  3973.         return $aRet;
  3974.     }
  3975.     
  3976.     function getAllBibleTranslationsForVerse($canonical_book_id$chapter_index$verse_index)
  3977.     {                
  3978.         $sSql "SELECT t.id, t.name as translation_name, t.url, v.content as verse_content, (case when language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) as group_order, l.id as language_id, l.righttoleft, l.text_style_override"
  3979.                 ." FROM bibletranslation t, biblebook b, biblechapter c, bibleverse v, language l"                
  3980.                 ." WHERE b.canonicalization_id = " $canonical_book_id " and t.id = b.translation_id and t.enabled and c.book_id = b.id and c.ordering = " $chapter_index " and v.chapter_id = c.id and v.indexdisplay = '" $verse_index "' and t.language_id = l.id";                                            
  3981.       $sSql .= " order by group_order, t.name";
  3982.   //  echo $sSql."<br>";   
  3983.           $aTemp $this->getNativeQueryResults($sSql);
  3984.           $nTempLen count($aTemp);
  3985.           $sPopupStartMark "~ppss~";
  3986.         $sPopupEndMark "~ppee~";
  3987.           for($i=0;$i<$nTempLen;$i++)
  3988.           {              
  3989.               $text $aTemp[$i]['verse_content'];              
  3990.               if(strpos($text,$sPopupStartMark) !== false)
  3991.               {
  3992.                   $text str_replace($sPopupStartMark'<sup><a data-toggle="popover" style="cursor: pointer; color:#007bff;"data-content="'$text);    
  3993.                 $text str_replace($sPopupEndMark'">*</a></sup>'$text);
  3994.                 
  3995.                 $aTemp[$i]['verse_content'] = $text;
  3996.               }
  3997.           }
  3998.            return $aTemp;  
  3999.     }
  4000.     
  4001.     function checkConcept($translation_id)
  4002.     {
  4003.         $sSql "select c.url from concept_work cl, concept c, expositionwork w, expositiontranslation t where t.id=".$translation_id " and t.work_id = w.id and cl.work_id = w.id and c.id = cl.concept_id and w.ispublic and t.ispublic limit 1";
  4004.         $sRet '';
  4005.         $aRet $this->getNativeQueryResults($sSql);
  4006.         if(count($aRet) > 0
  4007.             $sRet implode(''$aRet[0]);        
  4008.                 
  4009.         return $sRet;        
  4010.     }
  4011.     
  4012.     function checkUserBibleTrans($bookUrl$chapterIndex$verseIndex$nUserTranslationID)
  4013.     {
  4014.         $sSql "SELECT t.url FROM bibletranslation t, biblebook b, biblechapter c, bibleverse v, canonicalbiblebook cb"
  4015.                 ." WHERE t.id = " $nUserTranslationID " and cb.url = '" $bookUrl "' and b.canonicalization_id = cb.id and t.id = b.translation_id and t.enabled and c.book_id = b.id and c.ordering = " $chapterIndex " and v.chapter_id = c.id and v.indexdisplay = '" $verseIndex "' limit 1"
  4016.     // echo $sSql;           
  4017.         $sRet '';
  4018.         $aRet $this->getNativeQueryResults($sSql);
  4019.         if(count($aRet) > 0
  4020.             $sRet implode(''$aRet[0]);        
  4021.                 
  4022.         return $sRet;
  4023.     }
  4024.     
  4025.     // We will add a Bible icon to the right of the speaker icon,  if the current Swedenborg passage is 
  4026.     // a "main explanation" for a Bible chapter/verse. If the user clicks the Bible icon, it will open 
  4027.     // that "main-related" Bible chapter in a new column (desktop), or a new page (mobile UI).
  4028.     function getRelatedBibleRefForWork($passage_id,$translation_id$request)
  4029.     {        
  4030.         $sBibleStr '(';
  4031.         $nBibleTransID $request->getSession()->get('current_bible_translation_id');
  4032.         if($nBibleTransID != '')        
  4033.                $sBibleStr .= 'case when trans.id = ' $nBibleTransID ' then 1 else ';
  4034.                            
  4035.         $sBibleStr .= 'case when trans.language_id in (select language_id from expositiontranslation where id = ' $translation_id ') then 2 else case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 3 else 4 end end';
  4036.         if($nBibleTransID != '')        
  4037.                $sBibleStr .= ' end';                          
  4038.         
  4039.         $sBibleStr .= ')';              
  4040.     
  4041.         $sSql "SELECT '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc.ordering as link_spec, " $sBibleStr " as priority_order, cb.url as book_url, trans.url as trans_url, cc.ordering as chapter_order"
  4042.                 ."  FROM expositiontextunit t, canonicalbibleverse cv, canonicalbiblechapter cc, canonicalbiblebook cb, biblebook b, bibletranslation trans"
  4043.                 ." WHERE t.passage_id = " $passage_id " and (cv.id in (select verse_id from verse_passage where passage_id = " $passage_id " and iscorepassage) or cc.id in (select chapter_id from chapter_passage where passage_id = " $passage_id ") ) and cv.chapter_id = cc.id and cc.book_id = cb.id and b.canonicalization_id = cb.id and b.translation_id = trans.id and trans.enabled order by priority_order asc, trans.languagedefault desc limit 1";
  4044.    //  echo $sSql."<br>";   
  4045.            $aRet = array();
  4046.         $aTemp $this->getNativeQueryResults($sSql);
  4047.         if(count($aTemp) > 0
  4048.             $aRet $aTemp[0];        
  4049.                 
  4050.         return $aRet;
  4051.     }
  4052.     
  4053.     function getNextPrevConcept($concept_id)
  4054.     {
  4055.         $sSql "SELECT c.id, c.url FROM concept c, concept_work cl where c.id = cl.concept_id"
  4056.                 ." order by c.url";
  4057.      //           echo $sSql."<br>";
  4058.         $aRet = array();
  4059.         $aTemp $this->getNativeQueryResults($sSql);
  4060.         $sPrev "";
  4061.         $sNext "";
  4062.         if(count($aTemp) > 0
  4063.         {            
  4064.             $bPass false;
  4065.             foreach ($aTemp as $c)
  4066.             {
  4067.                 $nCurrID $c['id'];
  4068.                 
  4069.                 if($bPass)
  4070.                 {
  4071.                     $sNext $c['url'];
  4072.                     break;
  4073.                 }
  4074.                 
  4075.                 if($nCurrID == $concept_id)
  4076.                     $bPass true;                
  4077.                 
  4078.                 if(!$bPass)
  4079.                 {
  4080.                     $sPrev $c['url'];
  4081.                 }                
  4082.             }        
  4083.         }   
  4084.         
  4085.         $aRet['prev_concept_url'] = $sPrev;
  4086.         $aRet['next_concept_url'] = $sNext;             
  4087.         return $aRet;         
  4088.     }   
  4089.     
  4090.     // Get PDF resources for bible chapter
  4091.     function getCommentaryWithDocForBible($book$chapter_order$isCanonical=false)
  4092.     {
  4093.         if($isCanonical)
  4094.             $cbook $book;
  4095.         else
  4096.             $cbook $book->getCanonicalization();
  4097.         
  4098.         $nCBookId $cbook->getId();
  4099.         
  4100.         // get commentary from gced
  4101.         $sLinkStart '/bundles/ncbsw/resource/publicfile/';
  4102.         $sSql "SELECT r.title as name, ('" $sLinkStart "' || r.publicfile) as public_file, 1 as ordering from resource r, resource_bibleref rb, canonicalbiblechapter cc"                
  4103.                 ." WHERE rb.book_id = " $nCBookId " and r.publicfile like 'dbsn%' and r.id = rb.resource_id and cc.id = rb.chapter_id and cc.ordering = " $chapter_order " and r.publish";    
  4104.         
  4105.         // get commentary from ncbsw translations        
  4106.         $sLinkStart '/bundles/ncbsw/translation/';
  4107.         $sSql .= " union SELECT name, ('" $sLinkStart "' || public_file) as public_file, 2 as ordering from expositiontranslation"                
  4108.                 ." WHERE id in (select translation_id from expositiontranslationref where book_id = " $nCBookId ") and type_id = " $this->TRANSLATION_TYPE_ID_FILE " and ispublic and public_file is not null order by ordering, name";    
  4109.    //   echo $sSql."<br>";        
  4110.         return $this->getNativeQueryResults($sSql);
  4111.     }  
  4112.     
  4113.     function getExplainChapterID($vTranslationID$vUserID)
  4114.     {        
  4115.         $nRet null;         
  4116.             
  4117.         if($vUserID != '')
  4118.         {
  4119.             $nUserLevelID null;
  4120.             $sSql "select \"UserLevelID\" from \"user\" where \"UserID\" = " $vUserID " and \"UserLevelID\" in (-1, 1, 2, 3, 5, 6)";
  4121.     //     echo $sSql."<br>";    
  4122.             $aTemp $this->getNativeQueryResults($sSql);          
  4123.             if(count($aTemp) <= 0)
  4124.                 return null;
  4125.             else
  4126.                 $nUserLevelID current($aTemp[0]);    
  4127.         
  4128.             $sSql "select id from vchapterexplanationforchecking where translation_id = " $vTranslationID;
  4129.             
  4130.             if($nUserLevelID == $this->USER_LEVEL_ID_EXPLANATION_AUTHOR)
  4131.                 $sSql .= " and (user_id = " $vUserID " or user_id is null)";    
  4132.                         
  4133.     //     echo $sSql."<br>";    
  4134.             $aTemp $this->getNativeQueryResults($sSql);             
  4135.             if(count($aTemp) > 0)
  4136.             {                                    
  4137.                 $nRet $aTemp[0]['id'];                    
  4138.             }
  4139.         }
  4140.         return $nRet;
  4141.     }
  4142.     
  4143.     function EscapeTextForRegex($vText)
  4144.     {
  4145.         $sRet "replace(replace(replace(replace(" $vText ", ')', '\)'), '(', '\('), ']', '\]'), '[', '\[')";
  4146.         return $sRet;
  4147.     }
  4148.     
  4149.     // Convert time like 00:12:22 to seconds
  4150.     function convertTimeToSeconds($vTime)
  4151.     {        
  4152.         sscanf($vTime"%d:%d:%d"$hours$minutes$seconds);    
  4153.         $sRet $hours 3600 $minutes 60 $seconds;
  4154.         return $sRet;
  4155.     }
  4156.     
  4157.     function getOTLERefForBible($aVerseInfo$bChapter$bCheck=false)
  4158.     {              
  4159.         if(empty($aVerseInfo))
  4160.             return array();
  4161.     
  4162.         // 1/5/2022: Change to show all videos inc. non-OTLE.                
  4163.         $aChapter = array();
  4164.         $sVerseCChapterIDs $aVerseInfo['CChapterIDs'];    
  4165.         $sCVerseIDs $aVerseInfo['CVerseIDs'];   
  4166.                 
  4167.    /*     foreach($chapters as $chapter) {
  4168.             if($chapter === null) {
  4169.                 continue;
  4170.             }
  4171.             $canonicalChapter = $chapter->getCanonicalization();
  4172.             if($canonicalChapter != null) 
  4173.             {                              
  4174.                 $aChapter[] = $canonicalChapter->getId();                   
  4175.             }
  4176.         }*/
  4177.         
  4178.      //   $sChapters = '';        
  4179.     //    if($bChapter)
  4180.             $sChapters $aVerseInfo['CChapterIDs']; 
  4181.         
  4182.         $aRet = array();
  4183.         $aRet['otle_nonmusic'] = null;
  4184.            $aRet['otle_music'] = null;
  4185.              
  4186.   /*      if($sChapters != '' && $sVerseCChapterIDs != '')
  4187.             $sChapters .= ','.$sVerseCChapterIDs;
  4188.         else if($sVerseCChapterIDs != '')
  4189.             $sChapters = $sVerseCChapterIDs; */
  4190.         
  4191.         if(!empty($sChapters))
  4192.         {            
  4193.             $aVerseChapter $this->getVerseChapterInfo($sCVerseIDs);
  4194.         
  4195.             $sSql "select * from (" $this->getOTLESqlSelectStr() . ", cc.ordering as chapter_order, cb1.ordering as start_verse, cb2.ordering as end_verse, case when e.youtube_id is null then 2 else 1 end as video_order1";
  4196.             $sSql .= " FROM show s, embed e, show_bibleref sr left join canonicalbibleverse as cb1 on from_verse_id = cb1.id ";
  4197.             $sSql .= " left join canonicalbibleverse as cb2 on to_verse_id = cb2.id ";
  4198.             $sSql .= " left join canonicalbiblechapter as cc on sr.chapter_id = cc.id ";
  4199.             $sSql .= " WHERE ( ";
  4200.             
  4201.             if($bChapter)
  4202.                 $sSql .= " (sr.chapter_id in (" $sChapters "))";
  4203.             else
  4204.             {
  4205.                 $sSql .= " (sr.chapter_id in (" $sChapters ") and from_verse_id is null and to_verse_id is null)";
  4206.             
  4207.                 $sSql .= " or ( to_verse_id is null and sr.from_verse_id in (" $sCVerseIDs ") )";
  4208.                 
  4209.                 if(!empty($aVerseChapter))
  4210.                 {                
  4211.                     foreach($aVerseChapter as $vc)
  4212.                     {                                        
  4213.                         $sSql .= " or ( to_verse_id is not null and sr.chapter_id = " $vc['chapter_id'] . " and cb1.ordering <= " $vc['min_order'] . " and cb2.ordering >= " $vc['max_order'] . " )";
  4214.                     }                
  4215.                 }
  4216.             }
  4217.             
  4218.             $sSql .= ") and s.id = sr.show_id and e.visibilitydefault";
  4219.      //   $sSql .= " and s.is_otle";
  4220.             $sSql .= " and s.embed_id = e.id";
  4221.             
  4222.             if($bCheck)
  4223.                   $sSql .= " limit 1";
  4224.          //     else
  4225.           //        $sSql .= " limit 5";
  4226.           
  4227.           $sSql .= ") as t order by video_order1";    
  4228.                   
  4229.     //     echo $sSql."<br>";
  4230.              $aRet = array();   
  4231.             $aTemp $this->getNativeQueryResults($sSql);
  4232.             $aOTLE = array();
  4233.             $aOTLE_Music = array();
  4234.                foreach($aTemp as $temp)
  4235.                {
  4236.                    if($temp['showtype_id'] == $this->OTLE_SHOW_TYPE_ID_MUSIC)
  4237.                        $aOTLE_Music[] = $temp;
  4238.                    else
  4239.                        $aOTLE[] = $temp;
  4240.                }   
  4241.                
  4242.                $aRet['otle_nonmusic'] = $this->checkOTLELinks($aOTLE);
  4243.                $aRet['otle_music'] = $this->checkOTLELinks($aOTLE_Music);    
  4244.          }
  4245.          
  4246.            return $aRet;  
  4247.     }
  4248.     
  4249.     function getOTLESqlSelectStr()
  4250.     {                       
  4251.         $sSql "SELECT distinct on (s.id) s.id, s.title, e.description, e.youtube_id, sr.time, s.showtype_id, e.location, case when e.youtube_id is null then 2 else 1 end as video_order";
  4252.            return $sSql;  
  4253.     }
  4254.     
  4255.     function getVerseChapterInfo($CVerseIDs)
  4256.     {                
  4257.         $sSql "SELECT chapter_id, min(ordering) as min_order, max(ordering) as max_order from canonicalbibleverse"
  4258.                 ." WHERE id in (".$CVerseIDs ") group by chapter_id";
  4259.   //  echo $sSql."<br>";
  4260.         $aRet $this->getNativeQueryResults($sSql);            
  4261.         return $aRet;
  4262.     }
  4263.     
  4264.     function getOTLERefForWork($passage_id$bCheck=false)
  4265.     {  
  4266.         // 1/5/2022: Change to show all videos inc. non-OTLE.
  4267.         if(empty($passage_id))
  4268.             return array();
  4269.                                        
  4270.         $sSql $this->getOTLESqlSelectStr() . ", null as chapter_order, null as start_verse, null as end_verse";
  4271.         $sSql .= " FROM show s, embed e, show_workref sr";
  4272.         $sSql .= " WHERE sr.passage_id = " $passage_id " and s.id = sr.show_id and e.visibilitydefault";
  4273.      //   $sSql .= " and s.is_otle";
  4274.         $sSql .= " and s.embed_id = e.id";
  4275.         $sSql .= " and s.showtype_id <> " $this->OTLE_SHOW_TYPE_ID_MUSIC;
  4276.         $sSql .= " order by s.id desc, sr.time";
  4277.         
  4278.         if($bCheck)
  4279.               $sSql .= " limit 1";
  4280.               
  4281.     // echo $sSql."<br>";
  4282.         $aRet $this->getNativeQueryResults($sSql);
  4283.          $aRet $this->checkOTLELinks($aRet);
  4284.            return $aRet;  
  4285.     }
  4286.     
  4287.     function checkOTLELinks($vRet)
  4288.     {        
  4289.         if(empty($vRet))
  4290.             return $vRet;
  4291.     
  4292.         $nDelaySeconds 5;
  4293.          $nLen count($vRet); 
  4294.            for($i=0;$i<$nLen;$i++)
  4295.            {                                  
  4296.                $sLink '';    
  4297.             $sYoutubeID $vRet[$i]["youtube_id"];
  4298.             $sSameLink '';
  4299.             $vRet[$i]["show_time_in_seconds"] = 0;
  4300.             if(empty($sYoutubeID))
  4301.             {
  4302.                 $sLink $vRet[$i]["location"];                    
  4303.             }    
  4304.             else
  4305.             {
  4306.                 $sLink "https://www.youtube.com/embed/" $sYoutubeID;
  4307.                 $sTime $vRet[$i]["time"];
  4308.                     if(!empty($sTime))
  4309.                 {
  4310.                     $sSeconds $this->convertTimeToSeconds($sTime);
  4311.                     if(!empty($sSeconds))
  4312.                     {
  4313.                         $nShowTimeInSeconds $sSeconds $nDelaySeconds;
  4314.                         $sLink .= "?start=" $nShowTimeInSeconds "&autoplay=1";    
  4315.                         $vRet[$i]["show_time_in_seconds"] = $nShowTimeInSeconds;
  4316.                     }
  4317.                     else
  4318.                         $sLink .= "?autoplay=1";        
  4319.                     
  4320.                     if(strpos($sTime"00:") === 0)    
  4321.                         $vRet[$i]["time"] = substr($sTime3);
  4322.                 }
  4323.                 else
  4324.                 {
  4325.                     $vRet[$i]["time"] = "00:00";
  4326.                     $sLink .= "?autoplay=1";
  4327.                 }    
  4328.                                 
  4329.                 if($i && $sYoutubeID == $vRet[$i-1]["youtube_id"])
  4330.                 {
  4331.                     $vRet[$i-1]["same_youtube_id"] = $sYoutubeID;
  4332.                     $sSameLink $sYoutubeID;     
  4333.                 }    
  4334.                 
  4335.             //    if(empty($vRet[$i]["end_verse"]))
  4336.             //        $vRet[$i]["end_verse"] = $vRet[$i]["start_verse"];
  4337.                 
  4338.                 if($i && $vRet[$i]["start_verse"] == $vRet[$i-1]["start_verse"] && $vRet[$i]["end_verse"] == $vRet[$i-1]["end_verse"])
  4339.                 {
  4340.                     $vRet[$i]["same_verse_range"] = true;                         
  4341.                 }
  4342.                 else
  4343.                     $vRet[$i]["same_verse_range"] = false;
  4344.                 
  4345.                 if($i == || ($i && $sYoutubeID != $vRet[$i-1]["youtube_id"]))
  4346.                 {
  4347.                     $vRet[$i]["diff_prev_youtube_id"] = true;                         
  4348.                 } 
  4349.                 else
  4350.                     $vRet[$i]["diff_prev_youtube_id"] = false;     
  4351.                     
  4352.                 if($i == $nLen-|| !($vRet[$i]["start_verse"] == $vRet[$i+1]["start_verse"] && $vRet[$i]["end_verse"] == $vRet[$i+1]["end_verse"]))
  4353.                 {
  4354.                     $vRet[$i]["diff_next_verse_range"] = true;                         
  4355.                 } 
  4356.                 else
  4357.                     $vRet[$i]["diff_next_verse_range"] = false;     
  4358.                     
  4359.                 if($i == $nLen-|| $vRet[$i]["youtube_id"] != $vRet[$i+1]["youtube_id"])
  4360.                 {
  4361.                     $vRet[$i]["diff_next_youtube_id"] = true;                         
  4362.                 } 
  4363.                 else
  4364.                     $vRet[$i]["diff_next_youtube_id"] = false;                        
  4365.             }
  4366.             
  4367.             if(!empty($sLink))
  4368.                 $vRet[$i]["video_link"] = $sLink;
  4369.                 
  4370.             $vRet[$i]["same_youtube_id"] = $sSameLink;    
  4371.            } 
  4372.            
  4373.            return $vRet;
  4374.     }
  4375.     
  4376.     function getExplanationRefForWork($passage_id$language_id$bCheck=false)
  4377.     {               
  4378.         $aRet = array();
  4379.         if(empty($passage_id))
  4380.             return $aRet;
  4381.              
  4382.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English    
  4383.                     
  4384.         $sFilter ' p.id in (';
  4385.               
  4386.           $sFilter .= 'select ps.id
  4387. FROM refexposition re, textunit_combinedreference tc, expositiontextunit ts, expositiontextunit t1, expositiontextunit t2, expositionpassage ps, expositiondivision d1, expositiondivision da, expositionpassage p1, expositionpassage p2, expositionpassage pa'
  4388.                 .' WHERE ts.passage_id = ps.id and ts.id = tc.textunit_id and re.container_id = tc.combinedreference_id and t1.id = re.startlocation_id and t2.id = re.endlocation_id and t1.passage_id = p1.id and t2.passage_id = p2.id and p1.division_id = d1.id and pa.id = ' $passage_id ' and pa.division_id = da.id and da.work_id = d1.work_id and pa.ordering >= p1.ordering and pa.ordering <= p2.ordering) and w.swedenborgtype ';  
  4389.         $sFilter .= ' is null'
  4390.          $sSql1 "select array_to_string(array_agg(DISTINCT id), ',') from (SELECT distinct on (w.id) t.id" 
  4391.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  4392.                 ." WHERE " $sFilter;    
  4393.         $sSql1 .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id in ( ".$language_id"," $nDefaultLanguageID ") and t.ispublic and w.ispublic and t.url is not null and t.url <> ''";
  4394.         $sSql1 .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  4395.         $sSql1 .= " order by w.id, t.islanguagedefault desc";
  4396.         
  4397.         if($bCheck)
  4398.               $sSql1 .= " limit 1";
  4399.         
  4400.         $sSql1 .= ") as t";
  4401.         $aTrans $this->getNativeQueryResults($sSql1);         
  4402.         $sTransIDs '';
  4403.         if(count($aTrans) > 0)                      
  4404.             $sTransIDs implode(''$aTrans[0]);
  4405.             
  4406.         $bHasTrans = (!empty($sTransIDs));    
  4407.         
  4408.         $sSql "";
  4409.         if($bHasTrans
  4410.         {                 
  4411.             $sSql "SELECT distinct on (p.id) p.id, ec.category_id, t.translatedtitle AS title, (case when p.swedenborgsection is not null then p.swedenborgsection else cast(p.ordering as text) end) as num, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as link_spec, t.url as translation_url, d.url as division_url, case when t.language_id = " $language_id " then 1 else 2 end as lang_order"
  4412.                     ." FROM expositiontranslation t, expositionpassage p, expositiondivision d, expositionwork w"
  4413.                     ." join (select distinct on (wc.work_id) wc.work_id, c.id as category_id, c.name as category_name from work_category wc, expositioncategory c where wc.category_id = c.id and c.id in (12,13,14,41,42,46)) as ec on w.id = ec.work_id" 
  4414.                     ." WHERE " $sFilter;          
  4415.               $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (";
  4416.               
  4417.               $sSql .= $sTransIDs ") order by p.id, lang_order"
  4418.          } 
  4419.          
  4420.     /*      if($language_id != $nDefaultLanguageID)
  4421.           {
  4422.                  $sSql2 = "select array_to_string(array_agg(DISTINCT id), ',') from (SELECT distinct on (w.id) t.id"
  4423.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  4424.                 ." WHERE " . $sFilter;          
  4425.               $sSql2 .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id = ".$nDefaultLanguageID. " and t.ispublic and w.ispublic";
  4426.               $sSql2 .= " AND t.type_id = " . $this->TRANSLATION_TYPE_ID_TEXT;
  4427.               $sSql2 .= " order by w.id, t.islanguagedefault desc) as t";
  4428.               
  4429.               $aTrans2 = $this->getNativeQueryResults($sSql2); 
  4430.               
  4431.               $sTransIDs2 = '';
  4432.                 if(count($aTrans2) > 0)                      
  4433.                     $sTransIDs2 = implode('', $aTrans2[0]);
  4434.                     
  4435.               $bHasTrans2 = (!empty($sTransIDs2));                          
  4436.               if($bHasTrans2) 
  4437.               {                 
  4438.                  if($bHasTrans)
  4439.                      $sSql .= " union ";
  4440.           
  4441.                     $sSql .= " SELECT distinct on (p.id) p.id, ec.category_id, t.translatedtitle AS title, (case when p.swedenborgsection is not null then p.swedenborgsection else cast(p.ordering as text) end) as num, (case when w.swedenborgtype is not null then '" . $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK . "' else '" . $this->MULTI_URL_INDICATOR_EXPLANATION . "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as link_spec, t.url as translation_url, d.url as division_url"
  4442.                     ." FROM expositiontranslation t, expositionpassage p, expositiondivision d, expositionwork w"
  4443.                     ." join (select distinct on (wc.work_id) wc.work_id, c.id as category_id, c.name as category_name from work_category wc, expositioncategory c where wc.category_id = c.id and c.id in (12,13,14,41,42,46)) as ec on w.id = ec.work_id"
  4444.                     ." WHERE " . $sFilter;          
  4445.                     $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (" . $sTransIDs2 . ")"; 
  4446.                     
  4447.                     if($bHasTrans)
  4448.                     {
  4449.                         $sSql .= " and p.id not in (";
  4450.                         
  4451.                         $sSql .= "SELECT distinct p.id"
  4452.                         ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  4453.                         ." WHERE " . $sFilter;          
  4454.                         $sSql .= " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.id in (" . $sTransIDs . ")"; 
  4455.                         $sSql .= ")";
  4456.                     }                    
  4457.                 }
  4458.           } */
  4459.                     
  4460.           if($sSql != "")    
  4461.           {                    
  4462.               $sSql "select t2.*, case when category_id = 46 then 1 else case when category_id = 13 then 2 else case when category_id = 14 then 3 else case when category_id = 42 then 4 else 5 end end end end as ordering from (" $sSql ") as t2 order by ordering, title";
  4463.    //  echo $sSql."<br>";
  4464.                $aRet $this->getNativeQueryResults($sSql);  
  4465.            }
  4466.            return $aRet;
  4467.     }
  4468.     
  4469.     function getLangNoWordBoundary()
  4470.     {
  4471.         $aRet = array($this->LANGUAGE_ID_CHINESE$this->LANGUAGE_ID_JAPANESE$this->LANGUAGE_ID_THAI$this->LANGUAGE_ID_BURMESE$this->LANGUAGE_ID_MALAYALAM$this->LANGUAGE_ID_GEORGIAN$this->LANGUAGE_ID_AMHARIC$this->LANGUAGE_ID_KOREAN);
  4472.         return $aRet;
  4473.     }
  4474.     
  4475.     // Need to change the similar function on phpMaker site
  4476.     function getBoundaryStrForSql($vLanguageID)
  4477.     {        
  4478.         $aLangNoBoundary $this->getLangNoWordBoundary();
  4479.         $sBorderStr "\y";
  4480.         if(in_array($vLanguageID$aLangNoBoundary))
  4481.             $sBorderStr "";
  4482.     
  4483.         return $sBorderStr;    
  4484.     }
  4485.     
  4486.     function getBoundaryStrForPhp($vLanguageID)
  4487.     {        
  4488.         $aLangNoBoundary $this->getLangNoWordBoundary();
  4489.         $sBorderStr '\b';        
  4490.         if(in_array($vLanguageID$aLangNoBoundary))
  4491.             $sBorderStr '';
  4492.                 
  4493.         return $sBorderStr;    
  4494.     }
  4495.     
  4496.     function getAvailableTranslantion($vBookUrl$vDefaultTranslationID)
  4497.     {
  4498.         $sSql "SELECT t.id, t.url FROM bibletranslation t, biblebook b, canonicalbiblebook cb"
  4499.                 ." WHERE cb.url = '" str_replace("'""''"$vBookUrl) . "' and cb.id = b.canonicalization_id and t.id = b.translation_id order by (case when t.id = " $vDefaultTranslationID " then 1 else 2 end) limit 1";
  4500.   //    echo $sSql . "<br>"; 
  4501.         $aRet $this->getNativeQueryResults($sSql);                
  4502.         return $aRet[0];
  4503.     }
  4504.     
  4505.     function getBibleTranslationCredit($translation_url)
  4506.     {        
  4507.         $sSql "SELECT credit from bibletranslation"
  4508.                 ." WHERE url = '"str_replace("'""''"$translation_url) . "'";
  4509.  //    echo $sSql."<br>";
  4510.         $sRet null;
  4511.         $aTemp $this->getNativeQueryResults($sSql);
  4512.         if(count($aTemp) > 0
  4513.             $sRet $aTemp[0]['credit'];        
  4514.                 
  4515.         return $sRet
  4516.     } 
  4517.     
  4518.     function getExplanationRefForBible($aVerseInfo$request$bCheck=false)
  4519.     {            
  4520.         if(empty($aVerseInfo))
  4521.             return array();
  4522.         
  4523.         $canon = array();
  4524.         $nulls = array();
  4525.         $verseLanguage null;
  4526.         $sVerseIDs $aVerseInfo['CVerseIDs'];
  4527.         $verseLanguage $aVerseInfo['LanguageID'];
  4528.          
  4529.         if($verseLanguage == '')
  4530.             $verseLanguage $this->LANGUAGE_ID_ENGLISH;
  4531.         
  4532.         if($sVerseIDs == '') {
  4533.             return null;
  4534.         } else {                    
  4535.             return $this->getExplanationRefForBibleInfo($verseLanguage$sVerseIDs$request$bCheck);
  4536.         }
  4537.     } 
  4538.     
  4539.     function getExplanationRefForBibleInfo($language_id$sVerseIDs$request$bCheck=false)
  4540.     {            
  4541.         if($sVerseIDs == ''
  4542.             return array();
  4543.             
  4544.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English    
  4545.                     
  4546.         $sFilter " p.id in (SELECT DISTINCT passage_id FROM verse_passage"
  4547.                 ." WHERE verse_id in (" $sVerseIDs "))";
  4548.         
  4549.         $sFilter .= " and w.swedenborgtype is null and wc.category_id in (13,14,42)";
  4550.         
  4551.         $nUILanguageID $this->getUILanguageID($request);
  4552.         $nPreferredLanguageID $this->getUserPreferredLanguageID($request);
  4553.                     
  4554.         $nBookLanguageID $language_id;
  4555.         
  4556.         $sLangOrder "case when t.language_id = " $nBookLanguageID " then 1";
  4557.         $sLangFilter " and t.language_id in (" $nBookLanguageID;
  4558.         
  4559.         $sEndStr "";
  4560.         if($nBookLanguageID != $nUILanguageID)
  4561.         {
  4562.             $sLangOrder .= " else case when t.language_id = " $nUILanguageID " then 2";
  4563.             $sEndStr .= " end ";
  4564.             $sLangFilter .= "," $nUILanguageID;
  4565.         }
  4566.         
  4567.         if(!empty($nPreferredLanguageID) && $nBookLanguageID != $nPreferredLanguageID && $nUILanguageID != $nPreferredLanguageID)
  4568.         {
  4569.             $sLangOrder .= ' else case when t.language_id = ' $nPreferredLanguageID ' then 3';    
  4570.             $sEndStr .= " end ";
  4571.             $sLangFilter .= "," $nPreferredLanguageID;
  4572.         }
  4573.                                 
  4574.         if($nBookLanguageID != $this->LANGUAGE_ID_ENGLISH && $nUILanguageID != $this->LANGUAGE_ID_ENGLISH && $nPreferredLanguageID != $this->LANGUAGE_ID_ENGLISH)
  4575.         {
  4576.             $sLangOrder .= " else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH ." then 4";
  4577.             $sEndStr .= " end ";
  4578.             $sLangFilter .= "," $this->LANGUAGE_ID_ENGLISH;
  4579.         }
  4580.          
  4581.         $sLangOrder .= $sEndStr " end";
  4582.         $sLangFilter .= ")";
  4583.                 
  4584.         $sSql "SELECT distinct on (p.id) p.id, wc.category_id, w.swedenborgtype, t.translatedtitle AS title, p.swedenborgsection as num, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as ref_column_spec, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering"
  4585.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d, work_category wc"
  4586.                 ." WHERE " $sFilter;          
  4587.           $sSql .= " and t.work_id=w.id and d.work_id = w.id and w.id = wc.work_id and p.division_id = d.id and wc.category_id <> " $this->CATEGORY_ID_BIBLE_STUDY " and t.id in (";
  4588.           
  4589.           $sSql .= "SELECT distinct on (w.id) t.id"
  4590.                 ." FROM expositionwork w, expositiontranslation t, expositiontranslationtext tt, expositionpassage p, expositiondivision d"
  4591.                 ." WHERE " $sFilter;          
  4592.                 
  4593.           $sSql .=  " and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id " $sLangFilter" and t.ispublic and w.ispublic and t.id = tt.translation_id and tt.text is not null and tt.text <> ''";
  4594.           $sSql .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  4595.           $sSql .= " order by w.id, " $sLangOrder ", t.islanguagedefault desc)"
  4596.           
  4597.           if($bCheck)
  4598.               $sSql .= " limit 1";
  4599.                                             
  4600.           $sSql "select t2.*, case when category_id = 46 then 1 else case when category_id = 13 then 2 else case when category_id = 14 then 3 else case when category_id = 42 then 4 else 5 end end end end as category_order from (" $sSql ") as t2 order by category_order, work_order, title, ordering";                 
  4601.             
  4602.    //  echo $sSql."<br>";   
  4603.            return $this->getNativeQueryResults($sSql);  
  4604.     }
  4605.     
  4606.     function getBibleStoryName($story_id$locale)
  4607.     {
  4608.         $sSql "SELECT bsl.name "
  4609.                 ." FROM biblestory_language bsl, language l"
  4610.                 ." WHERE bsl.biblestory_id = " $story_id " and l.shortcode = '" $locale "' and l.id = bsl.language_id";
  4611.         $sRet '';
  4612.         $aRet $this->getNativeQueryResults($sSql);
  4613.         if(count($aRet) > 0
  4614.             $sRet implode(''$aRet[0]);        
  4615.                 
  4616.         return $sRet
  4617.     }
  4618.     
  4619.     function getBibleBookName($vLinkText$vBookID$vLanguageID)
  4620.     {    
  4621.         // check Bible name
  4622.         $sRet $vLinkText;
  4623.         $nPosLastSpace strrpos($vLinkText' ');    
  4624.         if ($nPosLastSpace !== FALSE)
  4625.         {
  4626.     //        $sBookName = trim(substr($vLinkText, 0, $nPosLastSpace));
  4627.             $sNum trim(substr($vLinkText$nPosLastSpace+1));
  4628.         }            
  4629.         
  4630.         $sSql2 "SELECT name from canonicalbiblebooklanguage where language_id = " $vLanguageID " and book_id  = " $vBookID " and not is_abbr order by is_standard desc";
  4631.     
  4632.     //echo $sSql2."<br>";    
  4633.         $sExistingName $this->getSingleData($sSql2);
  4634.         if(!empty($sExistingName))
  4635.         {
  4636.             $sTempSpace " ";
  4637.             if($this->isLanguageNoBoundary($vLanguageID))
  4638.                 $sTempSpace "";
  4639.             $sRet $sExistingName $sTempSpace $sNum;
  4640.         }
  4641.         return $sRet;
  4642.     }
  4643.     
  4644.     function getWorkBookName($vLinkText$vBookID$vLanguageID)
  4645.     {    
  4646.         // check work name
  4647.         $sRet $vLinkText;
  4648.         $sTempLink str_replace(" [""["$vLinkText);
  4649.         $nPosLastSpace strrpos($sTempLink' ');    
  4650.         if ($nPosLastSpace !== FALSE)
  4651.         {
  4652.         //    $sBookName = trim(substr($vLinkText, 0, $nPosLastSpace));
  4653.             $sNum trim(substr($sTempLink$nPosLastSpace+1));
  4654.             $sNum str_replace("["" ["$sNum);
  4655.         }
  4656.         
  4657.         $sSql2 "SELECT name from expositionworklanguage where language_id = " $vLanguageID " and work_id = " $vBookID " and not is_abbr order by is_standard desc";
  4658.     
  4659.     //echo $sSql2."<br>";
  4660.         $sExistingName $this->getSingleData($sSql2);
  4661.         if(!empty($sExistingName))
  4662.         {
  4663.             $sTempSpace " ";
  4664.             if($this->isLanguageNoBoundary($vLanguageID))
  4665.                 $sTempSpace "";
  4666.             $sRet $sExistingName $sTempSpace $sNum;
  4667.         }
  4668.         return $sRet;
  4669.     }
  4670.             
  4671.     function isLanguageNoBoundary($vLanguageID)
  4672.     {
  4673.         $aLangNoBoundary $this->getLangNoWordBoundary();
  4674.         return (in_array($vLanguageID$aLangNoBoundary));
  4675.     }
  4676.     
  4677.     function getSingleData($vSql)
  4678.     {
  4679.         $sRet '';
  4680.         $aRet $this->getNativeQueryResults($vSql);
  4681.         if(count($aRet) > 0
  4682.             $sRet implode(''$aRet[0]); 
  4683.                 
  4684.         return $sRet;
  4685.     }
  4686.     
  4687.     function getBiblio($translation_id$vOriginal)
  4688.     {        
  4689.         $sSql1 "select translationmethod_id from expositiontranslation where id = " $translation_id;
  4690.         $nTransMethodID $this->getSingleData($sSql1);
  4691.         $bMachineTranslated = ($nTransMethodID == $this->TRANSLATION_METHOD_ID_MACHINE);
  4692.     
  4693.         $sSql "SELECT b.*, bp.creators, l.name as license_name, l.terms as license_terms, cr.description as copyright from";        
  4694.         $sSql .= " translation_bibliographicdata tb, ";         
  4695.         $sSql .= " bibliographicdata b" $this->getBiblioJoinSqlStr($vOriginal) . " where ";
  4696.         $sSql .= " tb.translation_id = ".$translation_id " and tb.bibliographicdata_id = b.id";
  4697.    //  echo $sSql."<br>";
  4698.         $aRet $this->getNativeQueryResults($sSql);
  4699.         
  4700.         if(count($aRet) < && $bMachineTranslated)
  4701.         {                    
  4702.             $sSql "SELECT b.*, bp.creators, l.name as license_name, l.terms as license_terms, cr.description as copyright from";                         
  4703.             $sSql .= " bibliographicdata b" $this->getBiblioJoinSqlStr($vOriginal) . " where ";
  4704.             $sSql .= " b.id in (select machine_translation_bilio_id from parameter where id = "$this->NC_PARAMETER_ID ")";               
  4705.        //  echo $sSql."<br>";
  4706.             $aRet $this->getNativeQueryResults($sSql);
  4707.         }
  4708.         
  4709.         if(count($aRet) > 0
  4710.         {
  4711.             $aRet $aRet[0]; 
  4712.             $nBiblioID $aRet['id'];
  4713.             $sSql "SELECT * from publication where biblio_id = " $nBiblioID;
  4714.             $aRet['publications'] = $this->getNativeQueryResults($sSql); 
  4715.         }           
  4716.                 
  4717.         return $aRet;
  4718.     } 
  4719.     
  4720.     function getBiblioOriginal($translation_id)
  4721.     {        
  4722.         $sSql "SELECT b.*, bp.creators, l.name as license_name, l.terms as license_terms, cr.description as copyright, t.url as translation_url from translation_bibliographicdata tb, expositiontranslation t, bibliographicdata b" $this->getBiblioJoinSqlStr(true)
  4723.                 ." WHERE tb.translation_id in (select id from expositiontranslation where work_id in (select work_id from expositiontranslation where id = ".$translation_id ") and isoriginal) and tb.bibliographicdata_id = b.id and t.id = tb.translation_id";
  4724.   //   echo $sSql."<br>";
  4725.         $aRet $this->getNativeQueryResults($sSql);
  4726.         if(count($aRet) > 0)
  4727.         { 
  4728.             $aRet $aRet[0];
  4729.             $nBiblioID $aRet['id'];
  4730.             $sSql "SELECT * from publication where biblio_id = " $nBiblioID;
  4731.             $aRet['publications'] = $this->getNativeQueryResults($sSql); 
  4732.         }            
  4733.                 
  4734.         return $aRet;
  4735.     } 
  4736.         
  4737.     function getBiblioJoinSqlStr($vOriginal)
  4738.     {
  4739.         $sRet " LEFT JOIN (SELECT bp1.bibliographicdata_id, string_agg(CASE WHEN p.name is not null then p.name else ((((p.firstname)::text || CASE WHEN (p.middlename IS NULL) THEN ''::text ELSE (' '::text || (p.middlename)::text) END) || ' '::text) || (p.lastname)::text) end, ', '::text) AS creators FROM bibliographicdata_person bp1, person p WHERE (bp1.person_id = p.id";
  4740.         
  4741.         if($vOriginal)
  4742.             $sRet .= " and (bp1.role_id = " $this->PERSON_ROLE_ID_AUTHOR " or bp1.role_id is null)";
  4743.         else
  4744.             $sRet .= " and bp1.role_id = " $this->PERSON_ROLE_ID_TRANSLATOR;
  4745.          
  4746.         $sRet .= ") GROUP BY bp1.bibliographicdata_id) bp ON (b.id = bp.bibliographicdata_id)";
  4747.         $sRet .= " LEFT JOIN lnccopyrightholder cr on b.copyright_id = cr.id";
  4748.         $sRet .= " LEFT JOIN license l on b.license_id = l.id";
  4749.                 
  4750.         return $sRet;
  4751.     }
  4752.         
  4753.     function getCurrUserLevel($request)
  4754.     {
  4755.         return $request->getSession()->get('user_level'); 
  4756.     } 
  4757.     
  4758.     function getNextPrevConceptUrl($translation_id$nLanguageID$locale)
  4759.     {        
  4760.         $nLocaleLangID $this->getLanguageIDByShortCode($locale);
  4761.         $sSql "select * from (SELECT distinct on (c.id) c.id, t.id as translation_id, t.url, case when t.language_id = " $nLocaleLangID " then 1 else case when t.language_id = " $nLanguageID " then 2 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3 else 4 end end end as lang_order FROM concept c, concept_work cl, expositiontranslation t where c.id = cl.concept_id and cl.work_id = t.work_id"
  4762.                 ." order by c.id, lang_order) as t1 order by url";
  4763.           //      echo $sSql."<br>";
  4764.         $aRet = array();
  4765.         $aTemp $this->getNativeQueryResults($sSql);
  4766.         $sPrev "";
  4767.         $sNext "";
  4768.         if(count($aTemp) > 0)
  4769.         {            
  4770.             $nCurrConceptID $this->getConceptID($translation_id);
  4771.             $bPass false;
  4772.             foreach ($aTemp as $c)
  4773.             {
  4774.                 $nCurrID $c['id'];
  4775.                 
  4776.                 if($bPass)
  4777.                 {
  4778.                     $sNext $c['url'];
  4779.                     break;
  4780.                 }
  4781.                 
  4782.                 if($nCurrID == $nCurrConceptID)
  4783.                     $bPass true;                
  4784.                 
  4785.                 if(!$bPass)
  4786.                 {
  4787.                     $sPrev $c['url'];
  4788.                 }                
  4789.             }        
  4790.         }   
  4791.         
  4792.         $aRet['prev_concept_url'] = $sPrev;
  4793.         $aRet['next_concept_url'] = $sNext;             
  4794.         return $aRet;         
  4795.     }
  4796.     
  4797.     function getConceptTranslationUrl($conceptUrl$languageCode)
  4798.     {
  4799.         $sOrder "";
  4800.         if(!empty($languageCode))
  4801.         {            
  4802.             $sSql "SELECT t.url FROM concept c, concept_work cl, expositiontranslation t, language l where c.url = '" str_replace("'""''"$conceptUrl) . "' and c.id = cl.concept_id and cl.work_id = t.work_id and t.language_id = l.id"
  4803.                 ." order by case when l.bibliographiccode = '" $languageCode "' then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end limit 1";
  4804.         }        
  4805.         else
  4806.         {    
  4807.             $sSql "SELECT t.url FROM concept c, concept_work cl, expositiontranslation t where c.url = '" str_replace("'""''"$conceptUrl) . "' and c.id = cl.concept_id and cl.work_id = t.work_id"
  4808.                 ." order by case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end limit 1";
  4809.         }        
  4810.    //             echo $sSql."<br>";
  4811.         $sRet $this->getSingleData($sSql);              
  4812.         return $sRet;         
  4813.     }
  4814.     
  4815.     function IsSwedenborgWork($translationUrl)
  4816.     {
  4817.         $sSql "SELECT t.id FROM expositionwork w, expositiontranslation t where t.url = '" str_replace("'""''"$translationUrl) . "' and w.id = t.work_id and w.swedenborgtype is not null";
  4818.     //            echo $sSql."<br>";
  4819.         $nRet $this->getSingleData($sSql);              
  4820.         return (!empty($nRet));         
  4821.     }
  4822.     
  4823.     function getBibleTranslationID($translationUrl)
  4824.     {                
  4825.         $sSql "SELECT id FROM bibletranslation"
  4826.                  ." WHERE url = '" trim(str_replace("'""''"$translationUrl)) . "'";
  4827.  //    echo $sSql."<br>";   
  4828.            $sRet $this->getSingleData($sSql);  
  4829.         return $sRet;   
  4830.     }
  4831.     
  4832.     function getRowData($vSql)
  4833.     {
  4834.         $aRet = array();
  4835.         $aTemp $this->getNativeQueryResults($vSql);
  4836.         if(count($aTemp) > 0
  4837.             $aRet $aTemp[0];        
  4838.                 
  4839.         return $aRet
  4840.     }
  4841.     
  4842.     function getListData($vSql)
  4843.     {
  4844.         $aRet = array();
  4845.         $aTemp $this->getNativeQueryResults($vSql);
  4846.         if(count($aTemp) > 0
  4847.             $aRet $aTemp;        
  4848.                 
  4849.         return $aRet
  4850.     }
  4851.     
  4852.     function getBibleChapterList($translationUrl$translationUrl2$translationUrl3$bookUrl)
  4853.     {                
  4854.         $sSql "SELECT c.ordering FROM biblebook b, biblechapter c, bibletranslation t, canonicalbiblebook cb";
  4855.         $sSql .= " WHERE t.url = '" trim(str_replace("'""''"$translationUrl)) . "'";
  4856.         
  4857.         if(!empty($translation_id2) && $translation_id2 != '-none-'
  4858.         {
  4859.             $sSql .= " and cb.id in (SELECT cb.id FROM biblebook b, canonicalbiblebook cb, bibletranslation t" 
  4860.                 ." WHERE t.url = " trim(str_replace("'""''"$translationUrl2)) . " and b.canonicalization_id = cb.id and t.id = b.translation_id)";
  4861.         }  
  4862.         
  4863.         if(!empty($translation_id3) && $translation_id3 != '-none-'
  4864.         {
  4865.             $sSql .= " and cb.id in (SELECT cb.id FROM biblebook b, canonicalbiblebook cb, bibletranslation t" 
  4866.                 ." WHERE t.url = " trim(str_replace("'""''"$translationUrl3)) . " and b.canonicalization_id = cb.id and t.id = b.translation_id)";
  4867.         }  
  4868.         
  4869.         $sSql .= " and cb.url = '" trim(str_replace("'""''"$bookUrl)) . "'"
  4870.         $sSql .= " and t.id = b.translation_id and b.id = c.book_id and cb.id = b.canonicalization_id"
  4871.         $sSql .= " order by c.ordering";         
  4872.  //    echo $sSql."<br>";   
  4873.            $aRet $this->getListData($sSql);             
  4874.         return $aRet;   
  4875.     }
  4876.     
  4877.     function getLanguageIDByTranslation($translation_id)
  4878.     {                
  4879.         $sSql "select language_id from expositiontranslation where id = " $translation_id;
  4880.   //   echo $sSql."<br>";   
  4881.            $nRet $this->getSingleData($sSql);  
  4882.         return $nRet;   
  4883.     }
  4884.     
  4885.     function getBibleMultiColumnSpec($translationUrl$bookUrl$chapterIndex$verseStartIndex=null$verseEndIndex null)
  4886.     {
  4887.         $bible_multi_spec $this->MULTI_URL_INDICATOR_BIBLE '_' $translationUrl '_' $bookUrl;
  4888.         if($chapterIndex != null)
  4889.         {
  4890.             $bible_multi_spec .= '_' $chapterIndex;
  4891.           
  4892.           if($verseStartIndex != null)
  4893.           {
  4894.               $bible_multi_spec .= '_' $verseStartIndex;
  4895.               if($verseEndIndex != null)
  4896.                   $bible_multi_spec .= '-' $verseEndIndex;
  4897.           }    
  4898.         }
  4899.  //   echo $bible_multi_spec;
  4900.         return $bible_multi_spec;
  4901.     } 
  4902.            
  4903.     function getSwedenborgWorks($request$nLocaleLanguageID$nSelectedLangID)
  4904.     {             
  4905.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id, t.id as translation_id, t.url as translation_url, t.translatedtitle AS title, t.description, case when t.language_id = ".$nLocaleLanguageID ." then 1 else 2 end as lang_order, case when t.islanguagedefault then 1 else 2 end as default_order, w.swedenborgtype, wt.ordering as type_order"
  4906.         ." FROM expositiontranslation t, expositionworktype wt, expositionwork w"        
  4907.         ." WHERE w.swedenborgtype IS NOT NULL and t.work_id=w.id and w.swedenborgtype = wt.name";
  4908.        if(!empty($nSelectedLangID))
  4909.                $sSql .= " and t.language_id = ".$nSelectedLangID;
  4910.        else if($nLocaleLanguageID == $this->LANGUAGE_ID_ENGLISH)         
  4911.                $sSql .= " and t.language_id = ".$nLocaleLanguageID;
  4912.        else
  4913.                $sSql .= " and t.language_id in (" $this->LANGUAGE_ID_ENGLISH ", ".$nLocaleLanguageID.")";
  4914.                                       
  4915.        $sSql .= " and w.swedenborgtype not in ('scientific', 'transitional')";        
  4916.                 
  4917.        $sSql .= " and t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT " and w.ispublic AND t.ispublic and t.url is not null and t.url <> '' order by w.id, lang_order, default_order) as w2 order by w2.type_order, w2.title";
  4918.    //  echo $sSql."<br>";    
  4919.          $aRet = array();   
  4920.         $aTemp $this->getNativeQueryResults($sSql);  
  4921.            $nLen count($aTemp);           
  4922.            foreach($aTemp as $temp)
  4923.            {
  4924.                $aRet[$temp['swedenborgtype']][] = $temp;
  4925.            }
  4926.            
  4927.            return $aRet
  4928.     }  
  4929.     
  4930.     // Show the transitional and/or scientific and  works after the main list
  4931.     function getSwedenborgWorks2($request$nLocaleLanguageID$nSelectedLangID)
  4932.     {             
  4933.         $sSql " select * from (SELECT distinct on (w.id) w.id as work_id, t.id as translation_id, t.url as translation_url, t.translatedtitle || case when wd.datecreated is null then '' else ' (' || wd.datecreated || ')' end AS title, t.description, case when t.language_id = ".$nLocaleLanguageID ." then 1 else 2 end as lang_order, case when t.islanguagedefault then 1 else 2 end as default_order, w.swedenborgtype, wt.ordering as type_order, wd.datecreated as order2, t.translatedtitle as order3"
  4934.         ." FROM expositiontranslation t, expositionworktype wt, expositionwork w"  
  4935.         ." left join vworkdatecreated wd on w.id = wd.work_id"      
  4936.         ." WHERE w.swedenborgtype IS NOT NULL and t.work_id=w.id and w.swedenborgtype = wt.name";
  4937.        if(!empty($nSelectedLangID))
  4938.                $sSql .= " and t.language_id = ".$nSelectedLangID;
  4939.        else if($nLocaleLanguageID == $this->LANGUAGE_ID_ENGLISH)         
  4940.                $sSql .= " and t.language_id = ".$nLocaleLanguageID;
  4941.        else
  4942.                $sSql .= " and t.language_id in (" $this->LANGUAGE_ID_ENGLISH ", ".$nLocaleLanguageID.")";
  4943.                                       
  4944.        $bShowScientific $this->showScientific($request);
  4945.        if(!$bShowScientific)
  4946.                $sSql .= " and w.swedenborgtype in ('transitional')";
  4947.        else
  4948.                $sSql .= " and w.swedenborgtype in ('scientific', 'transitional')";                
  4949.                 
  4950.        $sSql .= " and t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT " and w.ispublic AND t.ispublic and t.url is not null and t.url <> '' order by w.id, lang_order, default_order) as w3 order by type_order, order2 desc NULLS LAST, order3";
  4951.  //    echo $sSql."<br>";    
  4952.          $aRet = array();   
  4953.         $aTemp $this->getNativeQueryResults($sSql);  
  4954.            $nLen count($aTemp);           
  4955.            foreach($aTemp as $temp)
  4956.            {
  4957.                $aRet[$temp['swedenborgtype']][] = $temp;
  4958.            }
  4959.            
  4960.            return $aRet
  4961.     } 
  4962.     
  4963.     function getSwedenborgWorkLanguages($request)
  4964.     {
  4965.         $sSql "SELECT id, (case when nativename is not null and nativename <> '' then nativename else name end) as name from language where id in (select distinct language_id FROM expositiontranslation";
  4966.         $sSql .= " WHERE type_id = " $this->TRANSLATION_TYPE_ID_TEXT " and ispublic and work_id in (select distinct id from expositionwork where ispublic and swedenborgtype is not null"
  4967.         $bShowScientific $this->showScientific($request);
  4968.         if(!$bShowScientific)
  4969.                $sSql .= " and swedenborgtype <> 'scientific'";
  4970.                 
  4971.         $sSql .= ")) order by name";         
  4972.  //    echo $sSql."<br>";   
  4973.            $aRet $this->getListData($sSql);             
  4974.         return $aRet;
  4975.     }
  4976.     
  4977.     function getConceptID($vTranslationId)
  4978.     {                
  4979.         $sSql "SELECT cl.concept_id"
  4980.                 ." FROM work_category wc, concept_work cl, expositiontranslation t" 
  4981.                 ." WHERE t.id = " $vTranslationId ."  and wc.category_id = " $this->CATEGORY_ID_CONCEPT " and wc.work_id = t.work_id and cl.work_id = t.work_id";
  4982.  //   echo $sSql;   
  4983.            $sRet null;
  4984.         $aTemp $this->getNativeQueryResults($sSql);
  4985.         if(count($aTemp) > 0
  4986.             $sRet $aTemp[0]['concept_id'];        
  4987.                 
  4988.         return $sRet;   
  4989.     }
  4990.     
  4991.     function showScientific($request)
  4992.     {
  4993.         $bRet false;
  4994.         // Let's show the Swedenborg Scientific works to users whose privileges are Administrator, 
  4995.         // Application Manager, OTLE Administrator, Writings Translator or Editor, Explanation Author, 
  4996.         // Editor, or Translator.
  4997.         $ul = array(-1,1,2,3,5,6,7,8,9,11,12,13,14);
  4998.         $nUserLevelID $this->getCurrUserLevel($request);
  4999.         if(in_array($nUserLevelID$ul))        
  5000.             $bRet true;
  5001.         
  5002.         return $bRet;
  5003.     }
  5004.     
  5005.     function canEditExplanation($request)
  5006.     {
  5007.         $bRet false;
  5008.         $ul = array(-1,1,2,3,5,6,8,9,11,12,14);
  5009.         $nUserLevelID $this->getCurrUserLevel($request);
  5010.         if(in_array($nUserLevelID$ul))
  5011.             $bRet true;
  5012.             
  5013.         return $bRet;
  5014.     }
  5015.     
  5016.     function canEditWork($request)
  5017.     {
  5018.         $bRet false;
  5019.         $ul = array(-1,3,6,14);
  5020.         $nUserLevelID $this->getCurrUserLevel($request);
  5021.         if(in_array($nUserLevelID$ul))
  5022.             $bRet true;
  5023.             
  5024.         return $bRet;
  5025.     }
  5026.     
  5027.     function getChapterIDForTranslation($translationId$bible_chapterId)
  5028.     {
  5029.         $sSql "SELECT c.id"
  5030.                 ." FROM biblechapter c, biblebook b, bibletranslation t," 
  5031.                 ." (select b2.canonicalization_id, c2.ordering as chapter_order from biblechapter c2, biblebook b2 "
  5032.                 ." where c2.id = " $bible_chapterId " and c2.book_id = b2.id) as b3 "
  5033.                 ." WHERE t.id = " $translationId ." and b.translation_id = t.id"
  5034.                 ." and c.book_id = b.id and b.canonicalization_id = b3.canonicalization_id "
  5035.                 ." and c.ordering = b3.chapter_order limit 1";
  5036.   //  echo $sSql;   
  5037.            $sRet null;
  5038.         $aTemp $this->getNativeQueryResults($sSql);
  5039.         if(count($aTemp) > 0
  5040.             $sRet $aTemp[0]['id'];        
  5041.                 
  5042.         return $sRet;
  5043.     }    
  5044.     
  5045.     function getBibleWordPopupText($explanationID)
  5046.     {
  5047.         $nTextLength 300;
  5048.         $sSql "SELECT string_agg(tt.text, ' ' order by tu.ordering) as text FROM expositiontranslationtext tt , expositiontextunit tu where tt.translation_id = " $explanationID " and tt.placement_id = tu.id group by tt.translation_id";
  5049.  //   echo $sSql;    
  5050.            $sText $this->getSingleData($sSql);      
  5051.         $sRet $this->getTextWithinLength($sText$nTextLength"...");        
  5052.         return $sRet;
  5053.     }     
  5054.     
  5055.     function getTextWithinLength($text$length$str_end='')
  5056.     {
  5057.         if(strlen($text) > $length) {
  5058.             $nPosSpace strpos($text' '$length);
  5059.             if($nPosSpace !== false)
  5060.                 $text substr($text0$nPosSpace).$str_end;
  5061.             else
  5062.                 $text substr($text0$length).$str_end;    
  5063.         }
  5064.     
  5065.         return $text;
  5066.     }
  5067.     
  5068.     function getBibleWordPopupConceptInfo($explanationID$conceptID)
  5069.     {        
  5070.         $sSql "select ct.translatedtitle as title, c.url as concept_url"
  5071.                         ." FROM concept c, ";
  5072.         
  5073.         $sSql .= " (select cl.concept_id, trans.translatedtitle from concept_work cl, expositiontranslation trans where trans.id =" $explanationID " and cl.work_id = trans.work_id) as ct ";
  5074.         
  5075.         $sSql .= " WHERE c.id = " $conceptID " and c.id = ct.concept_id";                      
  5076.  //    echo $sSql."<br>"; 
  5077.            $aRet = array();
  5078.         $aTemp $this->getNativeQueryResults($sSql);
  5079.         if(count($aTemp) > 0
  5080.             $aRet $aTemp[0]; 
  5081.                           
  5082.         return $aRet;
  5083.     }
  5084.     
  5085.     function getChapterSummaryList($explanationID$bibleBookID)
  5086.     {
  5087.         $sSql1 "select language_id from expositiontranslation where id = " $explanationID;
  5088.         $nLanguageID =  $this->getSingleData($sSql1); 
  5089.     
  5090.         $sSql "SELECT distinct on (cc.ordering) t.id, t.translatedtitle as title, '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc.ordering as bible_spec, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, cc.ordering as chapter_order, case when t.id = " $explanationID " then 1 else case when t.language_id = " $nLanguageID " then 2 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3 end end end as lang_order";
  5091.         
  5092.         $sSql .= " FROM expositionwork w, expositiontranslation t, biblestory bs, story_work sw, canonicalbiblechapter cc, canonicalbiblebook cb, biblebook b, bibletranslation trans";
  5093.         $sSql .= " WHERE b.id = " $bibleBookID " and cc.book_id = b.canonicalization_id and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and w.ispublic and t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT " and t.ispublic and bs.chapter_id = cc.id and cc.book_id = cb.id and b.translation_id = trans.id"
  5094.         
  5095.         if($nLanguageID == $this->LANGUAGE_ID_ENGLISH)
  5096.             $sSql .= " and t.language_id = " $this->LANGUAGE_ID_ENGLISH;
  5097.         else
  5098.             $sSql .= " and t.language_id in (" $nLanguageID ", " $this->LANGUAGE_ID_ENGLISH ")";    
  5099.                                         
  5100.         $sSql .= " order by cc.ordering, lang_order, t.id desc";         
  5101.   //   echo $sSql."<br>";   
  5102.            $aRet $this->getListData($sSql);             
  5103.         return $aRet;
  5104.     }
  5105.     
  5106.     function getChapterSummaryListForSinglePage($explanationID$cBibleBookID)
  5107.     {
  5108.         $sSql1 "select language_id from expositiontranslation where id = " $explanationID;
  5109.         $nLanguageID =  $this->getSingleData($sSql1); 
  5110.     
  5111.         $sSql "SELECT distinct on (cc.ordering) t.id, t.translatedtitle as title, t.url, cc.ordering as chapter_order, case when t.id = " $explanationID " then 1 else case when t.language_id = " $nLanguageID " then 2 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3 end end end as lang_order";        
  5112.         $sSql .= " FROM expositionwork w, expositiontranslation t, biblestory bs, story_work sw, canonicalbiblechapter cc";
  5113.         $sSql .= " WHERE cc.book_id = " $cBibleBookID " and bs.chapter_id = cc.id and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and w.ispublic and t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT " and t.ispublic"
  5114.         
  5115.         if($nLanguageID == $this->LANGUAGE_ID_ENGLISH)
  5116.             $sSql .= " and t.language_id = " $this->LANGUAGE_ID_ENGLISH;
  5117.         else
  5118.             $sSql .= " and t.language_id in (" $nLanguageID ", " $this->LANGUAGE_ID_ENGLISH ")";    
  5119.                                         
  5120.         $sSql .= " order by cc.ordering, lang_order, t.id desc";         
  5121.   //   echo $sSql."<br>";   
  5122.            $aRet $this->getListData($sSql);             
  5123.         return $aRet;
  5124.     }
  5125.     
  5126.     function getUILocale($language_id)
  5127.     {                
  5128.         $sSql "SELECT l.shortcode FROM language l, languageforui lu" 
  5129.                 ." WHERE l.id = " $language_id " and l.id = lu.language_id";
  5130.   //   echo $sSql."<br>";   
  5131.            $nRet $this->getSingleData($sSql); 
  5132.         return $nRet;   
  5133.     }
  5134.     
  5135.     function getWorkTranslationLanguage($translationUrl)
  5136.     {        
  5137.         $sSql "SELECT language_id FROM expositiontranslation t where t.url = '" str_replace("'""''"$translationUrl) . "' limit 1";
  5138.    // echo $sSql;    
  5139.            $sRet $this->getSingleData($sSql);    
  5140.         return $sRet;
  5141.     }  
  5142.     
  5143.     function getBibleTranslationLanguage($translationUrl)
  5144.     {        
  5145.         $sSql "SELECT language_id FROM bibletranslation where url = '" str_replace("'""''"$translationUrl) . "' limit 1";
  5146. //    echo $sSql;    
  5147.            $sRet $this->getSingleData($sSql);    
  5148.         return $sRet;
  5149.     } 
  5150.     
  5151.     function getCVerseIDs($bookUrl$chapterIndex$verseIndex=null)
  5152.     {
  5153.         $sSql "";    
  5154.         
  5155.         if($verseIndex != null)
  5156.         {
  5157.             $sSql "select array_to_string(array_agg(cbv.id),',') as ids"
  5158.                         ." FROM canonicalbiblechapter cbc, canonicalbibleverse cbv, canonicalbiblebook cbb, bibleverse v, canonicalbibleverse_bibleverse cvv";
  5159.         
  5160.             $sSql .= " where cbb.url = '" str_replace("'""''"$bookUrl) . "' and cbc.ordering = " $chapterIndex " and v.indexdisplay = '" str_replace("'""''"$verseIndex) . "' and cbc.book_id = cbb.id and cbv.chapter_id = cbc.id and v.id = cvv.bibleverse_id and cbv.id = cvv.canonicalbibleverse_id";                         
  5161.         }
  5162.         else
  5163.         {
  5164.             $sSql "select array_to_string(array_agg(cbv.id),',') as ids"
  5165.                         ." FROM canonicalbiblechapter cbc, canonicalbibleverse cbv, canonicalbiblebook cbb";
  5166.         
  5167.             $sSql .= " where cbb.url = '" str_replace("'""''"$bookUrl) . "' and cbc.ordering = " $chapterIndex " and cbc.book_id = cbb.id and cbv.chapter_id = cbc.id"
  5168.         }            
  5169.                           
  5170.  //    echo $sSql."<br>"; 
  5171.            $sRet $this->getSingleData($sSql);          
  5172.         return $sRet;
  5173.     }
  5174.     
  5175.     function getCChapterID($bookUrl$chapterIndex)
  5176.     {
  5177.         $sSql "select cbc.id"
  5178.                         ." FROM canonicalbiblechapter cbc, canonicalbiblebook cbb";
  5179.         
  5180.         $sSql .= " where cbb.url = '" str_replace("'""''"$bookUrl) . "' and cbc.ordering = " $chapterIndex " and cbc.book_id = cbb.id";                      
  5181.  //    echo $sSql."<br>"; 
  5182.            $sRet $this->getSingleData($sSql);          
  5183.         return $sRet;
  5184.     }
  5185.     
  5186.     function getBibleBookInfo($translationUrl$bookUrl)
  5187.     {
  5188.         $sSql "select b.name FROM biblebook b, canonicalbiblebook cb, bibletranslation t";        
  5189.         $sSql .= " where cb.url = '" str_replace("'""''"$bookUrl) . "' and t.url = '" str_replace("'""''"$translationUrl) . "' and b.translation_id = t.id and cb.id = b.canonicalization_id";                      
  5190.     // echo $sSql."<br>"; 
  5191.            $aRet $this->getRowData($sSql);             
  5192.         return $aRet;
  5193.     }
  5194.     
  5195.     function getVerseInfoForFrame($translationUrl$bookUrl$chapterIndex$verseIndex=null)
  5196.     {    
  5197.         $aRet = array(); 
  5198.         $verseLanguage $this->getBibleTranslationLanguage($translationUrl); 
  5199.         $sCVerseIDs $this->getCVerseIDs($bookUrl$chapterIndex$verseIndex); 
  5200.         $sCChapterIDs $this->getCChapterID($bookUrl$chapterIndex); 
  5201.         $aRet['CVerseIDs'] = $sCVerseIDs;
  5202.         $aRet['LanguageID'] = $verseLanguage;
  5203.         $aRet['CChapterIDs'] = $sCChapterIDs;        
  5204.         return $aRet;
  5205.     } 
  5206.     
  5207.     function isBadBot()
  5208.     {
  5209.         $bRet false;
  5210.         $useragent=@$_SERVER['HTTP_USER_AGENT'];
  5211.         if(preg_match('/petalbot|mj12bot/i',$useragent))
  5212.         {
  5213.             $bRet true;
  5214.         }
  5215.                 
  5216.         return $bRet;
  5217.     }       
  5218.     
  5219.     function getStoryTranslation($sStoryUrl$request)
  5220.     {        
  5221.         $locale $request->getLocale();             
  5222.         $sSql1 "select id from language where shortcode = '" trim(str_replace("'""''"$locale)) . "'";
  5223.         $nUILanguageID $this->getSingleData($sSql1);
  5224.         
  5225.         $sSql "select t.url FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs"
  5226.                 ." WHERE bs.url = '" str_replace("'""''"$sStoryUrl) . "' and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  5227.                 ." and w.ispublic AND t.ispublic order by case when t.language_id = " $nUILanguageID " then 1 else 2 end limit 1";
  5228.   //    echo $sSql . "<br>";          
  5229.         return $this->getSingleData($sSql); 
  5230.     }     
  5231.     
  5232.     function getUILanguageID($request)
  5233.     {
  5234.         $locale $request->getLocale();             
  5235.         $sSql1 "select id from language where shortcode = '" trim(str_replace("'""''"$locale)) . "'";
  5236.         $nUILanguageID $this->getSingleData($sSql1);
  5237.         return $nUILanguageID;
  5238.     }
  5239.     
  5240.     function getUserPreferredLanguageID($request)
  5241.     {
  5242.         $nLanguageID $request->getSession()->get('current_language_id');
  5243.         return $nLanguageID;
  5244.     }
  5245.             
  5246.     function getVerseExplanationsForVerse($verse_id)
  5247.     {    
  5248.         $sSql "SELECT t.id as translation_id, t.translatedtitle as explanationtitle, t.language_id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, (case when language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) as group_order"
  5249.        ." FROM (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_VERSE ") as bs, canonicalbibleverse cv, bibleverse v, canonicalbibleverse_bibleverse cvv,"
  5250.                     ." canonicalbiblechapter scc, expositionwork w, expositiontranslation t, story_work sw," 
  5251.                     ." biblechapter c, biblebook b, canonicalbiblebook cb, language l" 
  5252.                     ." WHERE v.id = " $verse_id
  5253.                     ." and v.id = cvv.bibleverse_id and cv.id = cvv.canonicalbibleverse_id"     
  5254.                     ." and bs.startverse_id = cv.id"                 
  5255.                     ." and cv.chapter_id = scc.id"
  5256.                     ." and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id"
  5257.                     ." and w.ispublic and t.ispublic"
  5258.                     ." and v.chapter_id = c.id and b.id = c.book_id and scc.book_id = cb.id and v.verse_id is null and t.language_id = l.id"
  5259.                     ." order by group_order, language_name, t.name";          
  5260.   //    echo $sSql."<br>";                
  5261.         $aRet $this->getNativeQueryResults($sSql);                
  5262.         return $aRet
  5263.     } 
  5264.     
  5265.     function getChapterExplanationForCombo($nChapterID)
  5266.     {    
  5267.         $sSql "SELECT t.id as translation_id, t.is_modern, t.translatedtitle as explanationtitle, t.language_id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, (case when language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) as group_order, case when t.islanguagedefault then 1 else 2 end as trans_order"
  5268.                 ." FROM expositionwork w, expositiontranslation t, expositiontranslationtext tt, story_work sw, biblestory bs, language l"
  5269.                 ." WHERE bs.chapter_id = " $nChapterID " and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and t.id = tt.translation_id and tt.text is not null and tt.text <> ''"                
  5270.                 ." and w.ispublic AND t.ispublic and t.language_id = l.id order by group_order, language_name, trans_order";
  5271.    //     echo $sSql."<br>";            
  5272.         return $this->getNativeQueryResults($sSql);
  5273.     } 
  5274.     
  5275.     function getVerseExplanationInText($request$explanations$nLanguageID)
  5276.     {
  5277.         $nUILanguageID $this->getUILanguageID($request);
  5278.         $nSelectedExplTransID $request->query->get('et'); 
  5279.         
  5280.     //    $nUserPreferredLanguageID = $this->getUserPreferredLanguageID($request);
  5281.                             
  5282.         $verseexplanation null;              
  5283.         $bGetID false;
  5284.         
  5285.         if(!empty($nSelectedExplTransID))
  5286.         {                    
  5287.             foreach($explanations as $expl) {    
  5288.                 $aTrans $expl->getTranslations(); 
  5289.                 foreach($aTrans as $trans) {               
  5290.                     if($trans->getId() == $nSelectedExplTransID)
  5291.                     {
  5292.                         $verseexplanation $trans;
  5293.                         $bGetID true;
  5294.                         break;
  5295.                     }
  5296.                 }
  5297.             }
  5298.         }
  5299.         
  5300.         if(!$bGetID)
  5301.         {
  5302.             foreach($explanations as $expl) {
  5303.                 $aTrans $expl->getTranslations();      
  5304.                 foreach($aTrans as $trans) {               
  5305.                     if($trans->getLanguage()->getId() == $nLanguageID)
  5306.                     {
  5307.                         $verseexplanation $trans;
  5308.                         $bGetID true;
  5309.                         break;
  5310.                     }
  5311.                 }
  5312.             }
  5313.         }
  5314.         
  5315.         if(!$bGetID)
  5316.         {
  5317.             foreach($explanations as $expl) {    
  5318.                 $aTrans $expl->getTranslations();    
  5319.                 if($trans->getLanguage()->getId() == $nUILanguageID)
  5320.                 {
  5321.                     $verseexplanation $trans;
  5322.                     $bGetID true;
  5323.                     break;
  5324.                 }
  5325.             }
  5326.         }
  5327.         
  5328.         if(!$bGetID)
  5329.         {
  5330.             foreach($explanations as $expl) {
  5331.                 $aTrans $expl->getTranslations();       
  5332.                 if($trans->getLanguage()->getId() == $this->LANGUAGE_ID_ENGLISH)
  5333.                 {
  5334.                     $verseexplanation $trans;
  5335.                     $bGetID true;
  5336.                     break;
  5337.                 }
  5338.             }
  5339.         }
  5340.         
  5341.         return $verseexplanation;              
  5342.     }
  5343.     
  5344.     // get table of contents of a work translation
  5345.     function getWorkTranslationTOC($nTranslationID$bCheck=false)
  5346.     {
  5347.         $sSql "select tt.toc_text, wt.startpassage_id, p.swedenborgsection as startpassagenum, p2.swedenborgsection as endpassagenum, t.url as translation_url, d.url as division_url, p.ordering as startpassageorder, p2.ordering as endpassageorder, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "' end) || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as link_spec"
  5348.         $sSql .= " from expositiontranslationtoc tt, expositionwork w, expositiontranslation t, expositiondivision d, expositionpassage p, expositionworktoc wt left join expositionpassage p2 on wt.endpassage_id = p2.id"
  5349.         $sSql .= " where tt.translation_id = " $nTranslationID " and tt.worktoc_id = wt.id and wt.startpassage_id = p.id and tt.translation_id = t.id and p.division_id = d.id and t.work_id = w.id order by p.ordering";
  5350.         
  5351.         if($bCheck)
  5352.               $sSql .= " limit 1";
  5353.               
  5354.  //    echo $sSql."<br>"; 
  5355.         $aRet $this->getNativeQueryResults($sSql);  
  5356.            $nLen count($aRet);           
  5357.            for($i=0;$i<$nLen;$i++)
  5358.            {                                  
  5359.             $startpassagenum $aRet[$i]["startpassagenum"];
  5360.             $endpassagenum $aRet[$i]["endpassagenum"];
  5361.             $sPassageStr $startpassagenum;
  5362.             if($endpassagenum != '')
  5363.                 $sPassageStr .= '-'.$endpassagenum;
  5364.             
  5365.             $aRet[$i]["link_text"] = $sPassageStr;
  5366.             
  5367.             $nNextStartPassageOrder '';
  5368.             if($i != $nLen-1)
  5369.             {
  5370.                 $nNextStartPassageOrder $aRet[$i+1]["startpassageorder"];
  5371.             }
  5372.             
  5373.             $aRet[$i]["nextstartpassageorder"] = $nNextStartPassageOrder;                    
  5374.            } 
  5375.        
  5376.         return $aRet;
  5377.     }
  5378.     
  5379.     function getBibleTransInfo($translation_url)
  5380.     {                
  5381.         $sSql "SELECT id, name"
  5382.                 ." FROM bibletranslation" 
  5383.                 ." WHERE url = '" trim(str_replace("'""''"$translation_url)) . "'";
  5384.   //   echo $sSql."<br>";   
  5385.            $aRet = array();
  5386.         $aTemp $this->getNativeQueryResults($sSql);
  5387.         if(count($aTemp) > 0
  5388.             $aRet $aTemp[0];        
  5389.                 
  5390.         return $aRet;   
  5391.     }
  5392.     
  5393.     function hasSliderItem($aVerseInfo$bInframe$request$bChapter false)
  5394.     {
  5395.         $bRet false;            
  5396.         if(!$bInframe)
  5397.           {
  5398.             $ref $this->getBibleRefPassage($aVerseInfo$bChapterfalsetrue);
  5399.             if(!empty($ref))
  5400.                 return true;
  5401.         
  5402.             $ref $this->getBibleRefPassage($aVerseInfo$bChaptertruetrue);
  5403.             if(!empty($ref))
  5404.                 return true;
  5405.         }
  5406.         
  5407.         $ref $this->getExplanationRefForBible($aVerseInfo$requesttrue);
  5408.         if(!empty($ref))
  5409.             return true;
  5410.         
  5411.         $ref $this->getGCEDRefForBible($aVerseInfo$bChaptertrue);
  5412.         if(!empty($ref))
  5413.             return true
  5414.                 
  5415.         $ref $this->getOTLERefForBible($aVerseInfo$bChaptertrue);
  5416.         if(!empty($ref))
  5417.             return true;         
  5418.                        
  5419.         $ref $this->getVerseCrossRefs($aVerseInfo$requesttrue);
  5420.         if(!empty($ref))
  5421.             return true;
  5422.         $ref $this->getBibleWordExplanations($aVerseInfo$requesttrue);
  5423.         if(!empty($ref))
  5424.             return true;
  5425.               
  5426.           $ref $this->getStoriesForVerses($aVerseInfo$requesttrue);
  5427.         if(!empty($ref))
  5428.             return true;
  5429.            
  5430.         $ref $this->getFirstExplainedVerse($aVerseInfo$request);
  5431.         if(!empty($ref))
  5432.             return true;
  5433.                             
  5434.         return $bRet;
  5435.     }
  5436.     
  5437.     function getBibleRefPassageNew($aVerseInfo$bChapter$bCorePassage$bCheck=false)
  5438.     {   
  5439.         $sVerseIDs $aVerseInfo['CVerseIDs'];
  5440.         $verseLanguage $aVerseInfo['LanguageID'];        
  5441.         $nBibleBookID $aVerseInfo['BookID'];
  5442.         
  5443.         if($verseLanguage == '')
  5444.             $verseLanguage $this->LANGUAGE_ID_ENGLISH;
  5445.                   
  5446.         $sCChapterIDs '';
  5447.         if($bChapter)
  5448.             $sCChapterIDs $aVerseInfo['CChapterIDs'];   
  5449.     
  5450.         if($sVerseIDs == '' && $sCChapterIDs == '') {
  5451.             return null;
  5452.         } else {           
  5453.             if($sVerseIDs != '')
  5454.             {      
  5455.                 $tempChapterIDs $this->checkWholeChapters($sVerseIDs);
  5456.                 if($tempChapterIDs != null)
  5457.                 {
  5458.                     if($sCChapterIDs != '')
  5459.                         $sCChapterIDs .= ',';
  5460.                     
  5461.                     $sCChapterIDs .= $tempChapterIDs
  5462.                 }    
  5463.             }                     
  5464.        
  5465.             return $this->getBibleRefPassageInfoNew($verseLanguage$sVerseIDs$sCChapterIDs$nBibleBookID$bCorePassage$bCheck);
  5466.         }
  5467.     } 
  5468.     
  5469.     function getBibleRefPassageInfoNew($language_id$sVerseIDs$sChapterIDs$nBibleBookID$bCorePassage$bCheck)
  5470.     {            
  5471.         if($sVerseIDs == '' && $sChapterIDs == ''
  5472.             return array();
  5473.             
  5474.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English    
  5475.         
  5476.         $sSql1 "select name from biblebook where id = "$nBibleBookID;
  5477.         $sBibleBookName $this->getSingleData($sSql1);
  5478.                     
  5479.         $sFilter " p.id";
  5480.          if(!$bCorePassage)
  5481.           {
  5482.               $sFilter .= " in (";
  5483.                                   
  5484.             if ($sVerseIDs <> '')
  5485.             {
  5486.                $sFilter .= 'SELECT DISTINCT passage_id FROM verse_passage'
  5487.                     .' WHERE  verse_id in (' $sVerseIDs ')';
  5488.             }
  5489.               $sFilter .= ") and p.id not ";
  5490.           }   
  5491.           
  5492.           $sFilter .= " in (";
  5493.     
  5494.         if ($sChapterIDs <> '')
  5495.         {
  5496.             $sFilter .= 'SELECT DISTINCT passage_id FROM chapter_passage'
  5497.                 .' WHERE chapter_id in (' $sChapterIDs ')';         
  5498.         }
  5499.         
  5500.         if ($sVerseIDs <> '')
  5501.         {
  5502.             if ($sChapterIDs <> '')
  5503.                  $sFilter .= " union ";
  5504.         
  5505.            $sFilter .= 'SELECT DISTINCT passage_id FROM verse_passage'
  5506.                 .' WHERE  verse_id in (' $sVerseIDs ')';    
  5507.                 $sFilter .= ' and iscorepassage';
  5508.         }        
  5509.         $sFilter .= ")";   
  5510.         
  5511.         $sSql "select t2.*, b.book_name, b.chapter_num, b.verse_num, b.chapter_num || ':' || b.verse_num as chapter_verse from (SELECT distinct on (p.id) p.id, w.swedenborgtype, t.translatedtitle AS title, p.swedenborgsection as num, '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "' || '_' || t.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as ref_column_spec, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering, case when t.language_id = " $language_id " then 1 else 2 end as lang_order"
  5512.                 ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  5513.                 ." WHERE " $sFilter;          
  5514.           $sSql .= " and w.swedenborgtype is not null and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and t.language_id in ( ".$language_id"," $nDefaultLanguageID ") and t.ispublic and w.ispublic and t.url is not null and t.url <> ''";
  5515.           $sSql .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  5516.           $sSql .= " order by p.id, lang_order, t.islanguagedefault desc"
  5517.           
  5518.           if($bCheck)
  5519.               $sSql .= " limit 1";
  5520.                         
  5521.           $sSql .= ") as t2,";
  5522.           
  5523.           // check ref chapter/verse
  5524.           if($bCorePassage)
  5525.           {
  5526.               $sSql .= "(";
  5527.               if ($sChapterIDs <> '')
  5528.               {
  5529.                   $sSql .= "SELECT cp.passage_id, '" str_replace("'""''"$sBibleBookName) . "' as book_name, cc.ordering as chapter_num, 0 as verse_num FROM chapter_passage cp, canonicalbiblechapter cc";
  5530.                 $sSql .= " WHERE cp.chapter_id in (" $sChapterIDs ") and cc.id = cp.chapter_id union ";
  5531.             }
  5532.             $sSql .= "SELECT vp.passage_id, '" str_replace("'""''"$sBibleBookName) . "' as book_name, cc.ordering as chapter_num, cv.ordering as verse_num FROM verse_passage vp, canonicalbibleverse cv, canonicalbiblechapter cc";
  5533.             $sSql .= " WHERE verse_id in (" $sVerseIDs ") and vp.iscorepassage and cv.id = vp.verse_id and cc.id = cv.chapter_id";
  5534.             $sSql .= ") as b";
  5535.           } 
  5536.           else
  5537.           {
  5538.               $sSql .= "(SELECT vp.passage_id, '" str_replace("'""''"$sBibleBookName) . "' as book_name, cc.ordering as chapter_num, cv.ordering as verse_num FROM verse_passage vp, canonicalbibleverse cv, canonicalbiblechapter cc";
  5539.             $sSql .= " WHERE verse_id in (" $sVerseIDs ") and not vp.iscorepassage and cv.id = vp.verse_id and cc.id = cv.chapter_id";
  5540.             $sSql .= ") as b";
  5541.           }
  5542.           
  5543.           $sSql .= " where b.passage_id = t2.id order by b.chapter_num, b.verse_num, t2.work_order, t2.title, t2.ordering";
  5544.                 
  5545.           //   echo $sSql."<br>";
  5546.            return $this->getNativeQueryResults($sSql);  
  5547.     }     
  5548.     
  5549.     function getAllListByCategory($vCategoryId$locale$request)
  5550.     {        
  5551.         $bConcept = ($vCategoryId == $this->CATEGORY_ID_CONCEPT);
  5552.         $bTopic = ($vCategoryId == $this->CATEGORY_ID_SPIRITUAL_TOPIC);
  5553.         $nSelectedLang null;
  5554.         $searchOptions $request->query->all();
  5555.         if(array_key_exists('language'$searchOptions))
  5556.         {
  5557.             $nLanguageID $searchOptions['language'];
  5558.             $nSelectedLang $nLanguageID;    
  5559.         }    
  5560.         else
  5561.             $nLanguageID $this->getLanguageIDByShortCode($locale);
  5562.         
  5563.         $sLangStr '';
  5564.         if($nLanguageID != null)
  5565.         {
  5566.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  5567.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5568.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  5569.                 
  5570.             $sLangStr .= ' 3 end';
  5571.             
  5572.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5573.                 $sLangStr .= ' end';
  5574.                 
  5575.             $sLangStr .= ' as language_order';        
  5576.         }
  5577.         else
  5578.             $sLangStr .= '1 as language_order';    
  5579.              
  5580.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id, t.id as tid,"
  5581.                 ."t.translatedtitle AS title, t.description, t.url, wo.feature_ordering,"
  5582.                 $sLangStr 
  5583.                 ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  5584.                 ", case when wo.is_featured then 1 else 2 end as is_featured,";
  5585.         
  5586.         if($bConcept)
  5587.         {
  5588.             $sSql .= "case when fi.image_file is not null then fi.image_file else case when fi2.image_file is not null then fi2.image_file else case when ci.image_file is not null then ci.image_file else  ti.image_file end end end as image_file, case when ci.image_file is not null then ci.image_title else case when fi.image_file is not null then fi.image_title else case when fi2.image_file is not null then fi2.image_title else ti.image_title end end end  as image_title";
  5589.         }
  5590.         else
  5591.         {
  5592.             $sSql .= "case when fi.image_file is not null then fi.image_file else case when fi2.image_file is not null then fi2.image_file else ti.image_file end end as image_file, case when fi.image_file is not null then fi.image_title else case when fi2.image_file is not null then fi2.image_title else ti.image_title end end as image_title";
  5593.         }
  5594.         
  5595.         $sSql .= ", t.primaryformat_id, case when t.primaryformat_id = " $this->PRIMARY_FORMAT_ID_VIDEO " then te.youtube_id else null end as youtube_id"
  5596.                 ." FROM expositiontranslation t join expositionwork w on t.work_id = w.id";
  5597.                 
  5598.         // featured image from the current translation
  5599.         $sSql .= " left join (select distinct on (t1.id) t1.id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on t.id = fi.id";
  5600.         
  5601.         // featured image from the translation with image 
  5602.         $sSql .= " left join (select distinct on (t1.work_id) t1.work_id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id order by t1.work_id, case when t1.language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) fi2 on t.work_id = fi2.work_id";
  5603.         
  5604.         // textunit image
  5605.         $sSql .= " left join (select distinct on (tt1.translation_id) tt1.translation_id, i.file as image_file, i.title as image_title from textunit_image ti, image i, expositiontranslationtext tt1 where ti.textunit_id = tt1.placement_id and ti.image_id = i.id and i.mediatype_id = 1) ti on t.id = ti.translation_id";
  5606.                     
  5607.        if($bConcept)
  5608.         {
  5609.             $sSql .= " left join (select distinct on (cl.work_id) cl.work_id as id, i.file as image_file, i.title as image_title from image i, conceptillustration ci1, concept_work cl where cl.concept_id = ci1.concept_id and ci1.image_id = i.id) ci on t.work_id = ci.id";
  5610.         }
  5611.          $sSql .= " left join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering, t2.is_featured from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") wo on w.id = wo.work_id"
  5612.          $sSql .= " left join (select distinct on (d.work_id) d.work_id, e.youtube_id from passage_media pm, expositionpassage p, expositiondivision d, embed e";
  5613.         $sSql .= " where e.youtube_id is not null and e.id = pm.embed_id";
  5614.         $sSql .= " and pm.passage_id = p.id and p.division_id = d.id order by d.work_id, p.ordering) te on w.id = te.work_id";
  5615.         $sSql .= " WHERE (t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $vCategoryId ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $vCategoryId "))";
  5616.         $sSql .= " and t.type_id = 1 "
  5617.         $sSql .= " and t.ispublic AND w.ispublic and t.url is not null and t.url <> ''"
  5618.         
  5619.         if(!empty($nSelectedLang))
  5620.             $sSql .= " and t.language_id = " $nSelectedLang
  5621.         else
  5622.         {    
  5623.             //if($bTopic && !$this->showEnglishTrans($nLanguageID))   
  5624.             //     $sSql .= " and t.language_id = " . $nLanguageID;
  5625.         }
  5626.                 
  5627.         $sSql .= " ORDER BY w.id, is_featured, language_order, lang_default_order) as t where language_order < 3"
  5628.                 ." ORDER BY language_order, is_featured, (case when image_file is not null and description is not null then 1 else case when image_file is not null then 2 else case when youtube_id is not null then 3 else case when description is not null then 4 else case when title is not null then 5 else 6 end end end end end), feature_ordering, title";        
  5629.              
  5630. //        echo $sSql . "<br>";         
  5631.         return $this->getNativeQueryResults($sSql);
  5632.     }      
  5633.     
  5634.     function getSearchedListByCategoryAndPathway($locale$request$vCategoryId,$vPathwayID)
  5635.     {       
  5636.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  5637.         $bTopic = ($vCategoryId == $this->CATEGORY_ID_SPIRITUAL_TOPIC);
  5638.         
  5639.         $sLangStr '';
  5640.         if($nLanguageID != null)
  5641.         {
  5642.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  5643.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5644.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  5645.                 
  5646.             $sLangStr .= ' 3 end';
  5647.             
  5648.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5649.                 $sLangStr .= ' end';
  5650.                 
  5651.             $sLangStr .= ' as language_order';        
  5652.         }
  5653.         else
  5654.             $sLangStr .= '1 as language_order';    
  5655.              
  5656.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id, t.id as tid,"
  5657.                 ."t.translatedtitle AS title, t.description, t.url,"
  5658.                 ." case when wt.display_order is null then wtg.display_order else wt.display_order end as display_order, " $sLangStr 
  5659.                 ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  5660.                 ", case when wo.is_featured then 1 else 2 end as is_featured"
  5661.                 ", case when fi.image_file is null then ti.image_file else fi.image_file end as image_file, case when fi.image_file is null then ti.image_title else fi.image_title end as image_title, t.primaryformat_id, case when t.primaryformat_id = " $this->PRIMARY_FORMAT_ID_VIDEO " then te.youtube_id else null end as youtube_id"
  5662.                 ." FROM expositiontranslation t join expositionwork w on t.work_id = w.id left join work_topic wt on t.work_id = wt.work_id left join work_topicgroup wtg on t.work_id = wtg.work_id";
  5663.         $sSql .= " left join (select distinct on (t1.id) t1.id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on t.id = fi.id";
  5664.         $sSql .= " left join (select distinct on (tt1.translation_id) tt1.translation_id, i.file as image_file, i.title as image_title from textunit_image ti, image i, expositiontranslationtext tt1 where ti.textunit_id = tt1.placement_id and ti.image_id = i.id and i.mediatype_id = 1";        
  5665.          $sSql .= ") ti on t.id = ti.translation_id";
  5666.          $sSql .= " left join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering, t2.is_featured from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") wo on w.id = wo.work_id";
  5667.          $sSql .= " left join (select distinct on (d.work_id) d.work_id, e.youtube_id from passage_media pm, expositionpassage p, expositiondivision d, embed e";
  5668.         $sSql .= " where e.youtube_id is not null and e.id = pm.embed_id";
  5669.         $sSql .= " and pm.passage_id = p.id and p.division_id = d.id order by d.work_id, p.ordering) te on w.id = te.work_id";
  5670.         $sSql .= " WHERE (t.work_id in (select work_id from work_topic where topic_id in (select expositiontopic_id from expositiontopic_group where expositiontopicgroup_id = " $vPathwayID "))"
  5671.                 ." OR t.work_id in (select work_id from work_topicgroup where topicgroup_id = " $vPathwayID ") )";    
  5672.          $sSql .= " AND (t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $vCategoryId ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $vCategoryId "))"
  5673.          $sSql .= " and t.type_id = 1"
  5674.          $sSql .= " and t.ispublic AND w.ispublic and t.url is not null and t.url <> ''";  
  5675.          
  5676.     //     if(!$this->showEnglishTrans($nLanguageID))   
  5677.                  $sSql .= " and t.language_id = " $nLanguageID;
  5678.                
  5679.          $sSql .= " ORDER BY w.id, is_featured, language_order, lang_default_order) as t where language_order < 3"
  5680.                 ." ORDER BY is_featured, (case when image_file is not null and description is not null then 1 else case when image_file is not null then 2 else case when youtube_id is not null then 3 else case when description is not null then 4 else case when title is not null then 5 else 6 end end end end end), display_order"
  5681.         
  5682.         $aRet $this->getNativeQueryResults($sSql);         
  5683.         if($bTopic)
  5684.         {
  5685.             $aTopic = array();
  5686.             if(count($aRet) > 1)
  5687.             {            
  5688.                 foreach($aRet as $r)
  5689.                 {
  5690.                     $aTemp = array();
  5691.                     $aTemp['translation_id'] = $r['tid'];
  5692.                     $aTemp['translation_url'] = $r['url'];                                    
  5693.                     $aTopic[] = $aTemp;
  5694.                 }            
  5695.             }             
  5696.             $request->getSession()->set('searched_topic_list'$aTopic);    
  5697.         } 
  5698.         return $aRet;
  5699.     }     
  5700.     
  5701.     function getAllBibleStories($locale$vLimit=null)
  5702.     {
  5703.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  5704.         
  5705.         $sLangStr '';
  5706.         if($nLanguageID != null)
  5707.         {
  5708.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  5709.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5710.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  5711.                 
  5712.             $sLangStr .= ' 3 end';
  5713.             
  5714.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5715.                 $sLangStr .= ' end';
  5716.                 
  5717.             $sLangStr .= ' as language_order';        
  5718.         }
  5719.         else
  5720.             $sLangStr .= '1 as language_order';
  5721.     
  5722.         $sSql "select * from (SELECT distinct on (w.id) t.translatedtitle AS title, t.description, t.url, bsw.story_id, bsw.story_url, t.url as translation_url, wo.feature_ordering"
  5723.             ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  5724.             ", case when wo.is_featured then 1 else 2 end as is_featured"
  5725.             ", case when fi.image_file is null then ti.image_file else fi.image_file end as image_file, case when fi.image_file is null then ti.image_title else fi.image_title end as image_title, t.primaryformat_id"            
  5726.             ", bsw.story_id, bsw.story_url, case when t.primaryformat_id = " $this->PRIMARY_FORMAT_ID_VIDEO " then case when bsw.youtube_id is null then te.youtube_id else bsw.youtube_id end else null end as youtube_id, " $sLangStr
  5727.             ." FROM expositiontranslation t, expositionwork w "
  5728.             ." join (select bs.id, bs.url as story_url, sw.work_id, sw.story_id, bs.name as story_name, bs.startverse_id, bsy.youtube_id from story_work sw, (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE                       
  5729.             ") as bs left join (select distinct on (se.story_id) se.story_id, e.youtube_id from story_embed se, embed e where e.youtube_id is not null and e.id = se.embed_id) as bsy on bs.id = bsy.story_id where bs.id = sw.story_id) bsw on w.id = bsw.work_id";
  5730.             
  5731.         $sSql .= " left join (select distinct on (t1.work_id) t1.work_id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on w.id = fi.work_id";
  5732.         $sSql .= " left join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering, t2.is_featured from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") wo on w.id = wo.work_id";        
  5733.         $sSql .= " left join (select distinct on (t2.work_id) t2.work_id, ti2.* from vexpositiontranslationimage ti2, expositiontranslation t2 where t2.id = ti2.translation_id) ti on w.id = ti.work_id"
  5734.         
  5735.         // work embed
  5736.         $sSql .= " left join (select distinct on (d.work_id) d.work_id, e.youtube_id from passage_media pm, expositionpassage p, expositiondivision d, embed e";
  5737.         $sSql .= " where e.youtube_id is not null and e.id = pm.embed_id";
  5738.         $sSql .= " and pm.passage_id = p.id and p.division_id = d.id order by d.work_id, p.ordering) te on w.id = te.work_id";
  5739.                         
  5740.         $sSql .= " WHERE t.ispublic and t.work_id=w.id AND w.ispublic";
  5741.         $sSql .= " and t.type_id = 1" 
  5742.             ." and story_url is not null" 
  5743.             ." ORDER BY w.id, language_order, lang_default_order";
  5744.             $sSql .= ") as t"
  5745.             ." where language_order < 3"
  5746.             ." ORDER BY language_order, is_featured, feature_ordering, (case when image_file is not null and description is not null then 1 else case when image_file is not null then 2 else case when youtube_id is not null then 3 else case when description is not null then 4 else case when title is not null then 5 else 6 end end end end end), title";
  5747.             
  5748.             if($vLimit != null && $vLimit 0)
  5749.              $sSql .= " limit " $vLimit;               
  5750.                
  5751. //  echo $sSql."<br>";              
  5752.         return $this->getNativeQueryResults($sSql);
  5753.     }
  5754.     
  5755.     function getPrimaryFormatList($request)
  5756.     {
  5757.         $sText $request->getSession()->get('ui_str')["primary.format.text"];
  5758.         $sVideo $request->getSession()->get('ui_str')["primary.format.video"];
  5759.         $sAudio $request->getSession()->get('ui_str')["primary.format.audio"];
  5760.         $sSql "SELECT id, case when id = " $this->PRIMARY_FORMAT_ID_TEXT " then '" str_replace("'""''"$sText) . "' else case when id = " $this->PRIMARY_FORMAT_ID_AUDIO " then '" str_replace("'""''"$sAudio) . "' else case when id = " $this->PRIMARY_FORMAT_ID_VIDEO " then '" str_replace("'""''"$sVideo) . "' end end end as name"
  5761.                 ." FROM primaryformat";
  5762.    // echo $sSql . "<br>";    
  5763.         $aRet $this->getNativeQueryResults($sSql);
  5764.         return $aRet;  
  5765.     }  
  5766.     
  5767.     function getListByCategory($locale$request$vCategoryId$vFormatID$vCBookID$vAuthorID=null)
  5768.     {       
  5769.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  5770.         $bBibleStory = ($vCategoryId == $this->CATEGORY_ID_BIBLE_STORY);
  5771.         $bTopic = ($vCategoryId == $this->CATEGORY_ID_SPIRITUAL_TOPIC);
  5772.                 
  5773.         $sLangStr '';
  5774.         if($nLanguageID != null)
  5775.         {
  5776.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  5777.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5778.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  5779.                 
  5780.             $sLangStr .= ' 3 end';
  5781.             
  5782.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5783.                 $sLangStr .= ' end';
  5784.                 
  5785.             $sLangStr .= ' as language_order';        
  5786.         }
  5787.         else
  5788.             $sLangStr .= '1 as language_order';    
  5789.              
  5790.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id, t.id as tid,"
  5791.                 ."t.translatedtitle AS title, t.description, t.url, " $sLangStr 
  5792.                 ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  5793.                 ", case when wo.is_featured then 1 else 2 end as is_featured"
  5794.                 ", case when fi.image_file is null then ti.image_file else fi.image_file end as image_file, case when fi.image_file is null then ti.image_title else fi.image_title end as image_title, t.primaryformat_id";
  5795.         if($bBibleStory)
  5796.         {
  5797.             $sSql .= ", bsw.story_id, bsw.story_url, case when t.primaryformat_id = " $this->PRIMARY_FORMAT_ID_VIDEO " then case when bsw.youtube_id is null then te.youtube_id else bsw.youtube_id end else null end as youtube_id";
  5798.         }
  5799.         else
  5800.             $sSql .= ", case when t.primaryformat_id = " $this->PRIMARY_FORMAT_ID_VIDEO " then te.youtube_id else null end as youtube_id";
  5801.                 
  5802.         $sSql .= " FROM expositiontranslation t join expositionwork w on t.work_id = w.id";
  5803.         $sSql .= " left join (select distinct on (t1.id) t1.id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on t.id = fi.id";
  5804.         $sSql .= " left join (select distinct on (tt1.translation_id) tt1.translation_id, i.file as image_file, i.title as image_title from textunit_image ti, image i, expositiontranslationtext tt1 where ti.textunit_id = tt1.placement_id and ti.image_id = i.id and i.mediatype_id = 1";
  5805.          $sSql .= ") ti on t.id = ti.translation_id";
  5806.          $sSql .= " left join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering, t2.is_featured from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") wo on w.id = wo.work_id";
  5807.          
  5808.          $sSql .= " left join (select distinct on (d.work_id) d.work_id, e.youtube_id from passage_media pm, expositionpassage p, expositiondivision d, embed e";
  5809.         $sSql .= " where e.youtube_id is not null and e.id = pm.embed_id";
  5810.         $sSql .= " and pm.passage_id = p.id and p.division_id = d.id order by d.work_id, p.ordering) te on w.id = te.work_id";
  5811.          
  5812.          if($bBibleStory)
  5813.         {
  5814.             $sSql .= " join (select bs.id, bs.url as story_url, sw.work_id, sw.story_id, bs.name as story_name, bs.startverse_id, bsy.youtube_id from story_work sw, (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE;
  5815.             if($vCBookID != '')
  5816.             {
  5817.                  $sSql .= " and startverse_id in (select cv.id from canonicalbibleverse cv, canonicalbiblechapter cc where cc.book_id = " $vCBookID " and cv.chapter_id = cc.id)";  
  5818.             } 
  5819.             
  5820.             $sSql .= ") as bs left join (select distinct on (se.story_id) se.story_id, e.youtube_id from story_embed se, embed e where e.youtube_id is not null and e.id = se.embed_id) as bsy on bs.id = bsy.story_id where bs.id = sw.story_id) bsw on t.work_id = bsw.work_id";
  5821.         }          
  5822.          $sSql .= " where w.ispublic";
  5823.          
  5824.          if(!$bBibleStory)
  5825.          {
  5826.              $sSql .= " and (t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $vCategoryId ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $vCategoryId "))";
  5827.          }
  5828.          
  5829.          if($vFormatID != '')
  5830.          { 
  5831.              //$sSql .= " and (t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" . $nCategoryId . ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" . $nCategoryId . ") or t.work_id IN (SELECT work_id FROM story_work))";  
  5832.              $sSql .= " and t.primaryformat_id = " $vFormatID;
  5833.          }
  5834.          
  5835.          if(!empty($vAuthorID))
  5836.          { 
  5837.              $sSql .= " and t.id in (select distinct t.id from bibliographicdata_person bp, translation_bibliographicdata tb, expositiontranslation t where bp.person_id = " $vAuthorID " and bp.bibliographicdata_id = tb.bibliographicdata_id and t.id = tb.translation_id)";  
  5838.          }
  5839.                   
  5840.          $sSql .= " and t.type_id = 1"
  5841.          $sSql .= " and t.ispublic AND t.url is not null and t.url <> ''";        
  5842.          $sSql .= " ORDER BY w.id, is_featured, language_order, lang_default_order) as t where language_order < 3"
  5843.                 ." ORDER BY is_featured, (case when image_file is not null and description is not null then 1 else case when image_file is not null then 2 else case when youtube_id is not null then 3 else case when description is not null then 4 else case when title is not null then 5 else 6 end end end end end), title";        
  5844.              
  5845.     //    echo $sSql . "<br>";  
  5846.         $aRet $this->getNativeQueryResults($sSql);                     
  5847.         if($bBibleStory)
  5848.         {
  5849.             $aStory = array();
  5850.             if(count($aRet) > 1)
  5851.             {            
  5852.                 foreach($aRet as $r)
  5853.                 {
  5854.                     $aTemp = array();
  5855.                     $aTemp['url'] = $r['story_url'];
  5856.                     $aTemp['commentary_url'] = $r['url'];
  5857.                     $aStory[] = $aTemp;
  5858.                 }            
  5859.             } 
  5860.             $request->getSession()->set('searched_bible_story_list'$aStory);
  5861.         }    
  5862.         else if($bTopic)
  5863.         {
  5864.             $aTopic = array();
  5865.             if(count($aRet) > 1)
  5866.             {            
  5867.                 foreach($aRet as $r)
  5868.                 {
  5869.                     $aTemp = array();
  5870.                     $aTemp['translation_id'] = $r['tid'];
  5871.                     $aTemp['translation_url'] = $r['url'];                                    
  5872.                     $aTopic[] = $aTemp;
  5873.                 }            
  5874.             }             
  5875.             $request->getSession()->set('searched_topic_list'$aTopic);    
  5876.         } 
  5877.         return $aRet;
  5878.     }  
  5879.     
  5880.     function getSearchedListByCategoryAndFormat($vCategoryId,$vFormatID,$locale$request)
  5881.     {
  5882.         return $this->getListByCategory($locale$request$vCategoryId$vFormatIDnull);
  5883.     }   
  5884.     
  5885.     function getSearchedListByCategoryAndBook($vCategoryId,$vCBookID,$locale$request)
  5886.     {
  5887.         return $this->getListByCategory($locale$request$vCategoryIdnull$vCBookID);
  5888.     } 
  5889.     
  5890.     function getBibleBookListForStory($request$locale)
  5891.     {                
  5892.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  5893.         
  5894.         $sLangStr '';
  5895.         if($nLanguageID != null)
  5896.         {
  5897.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  5898.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5899.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  5900.                 
  5901.             $sLangStr .= ' 3 end';
  5902.             
  5903.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  5904.                 $sLangStr .= ' end';
  5905.                 
  5906.             $sLangStr .= ' as language_order';        
  5907.         }
  5908.         else
  5909.             $sLangStr .= '1 as language_order';
  5910.    
  5911.    // Not used in combo     
  5912.  //       $sOldTestament = $request->getSession()->get('ui_str')["bible.testament.oldtestament"];
  5913.   //      $sNewTestament = $request->getSession()->get('ui_str')["bible.testament.newtestament"];
  5914.    //     $sApocrypha = $request->getSession()->get('ui_str')["bible.testament.apocrypha"];
  5915.     
  5916.         $sSql "select * from (SELECT distinct on (cb.id) cb.id as canonical_id, b.name, '' as testament_name, cb.testament_id, " $sLangStr
  5917.                 ." FROM biblebook b, biblechapter c, canonicalbiblebook cb, bibletranslation t" 
  5918.                 ." WHERE b.canonicalization_id = cb.id"
  5919.                 ." and t.id = b.translation_id and c.book_id = b.id"   
  5920.                 ." and cb.testament_id <> " $this->TESTAMENT_APOCRYPHA;      
  5921.         $sSql .= " order by cb.id, language_order) as t where language_order < 3"
  5922.                 ." order by testament_id, canonical_id"
  5923.                 
  5924.    //  echo $sSql."<br>";                   
  5925.         return $this->getNativeQueryResults($sSql);   
  5926.     }
  5927.     
  5928.     function hasSliderItemForWork($nPassageID,$nTranslationID$request$nLanguageID)
  5929.     {
  5930.         $bRet false;    
  5931.         
  5932.         $ref $this->getWorkTranslationTOC($nTranslationIDtrue);
  5933.         if(!empty($ref))
  5934.             return true;        
  5935.                 
  5936.   /*      $ref = $this->getWorkPassageRefs($nPassageID,$nTranslationID, $request, $nLanguageID, true);
  5937.         if(!empty($ref))
  5938.             return true; */
  5939.         
  5940.         $ref $this->getWorkRefForWork($nPassageID,$nTranslationID$nLanguageIDtrue);
  5941.         if(!empty($ref))
  5942.             return true
  5943.                 
  5944.         $ref $this->getExplanationRefForWork($nPassageID$nLanguageIDtrue);
  5945.         if(!empty($ref))
  5946.             return true;         
  5947.                        
  5948.         $ref $this->getGCEDRefForWork($nPassageIDtrue);
  5949.         if(!empty($ref))
  5950.             return true;
  5951.         $ref $this->getOTLERefForWork($nPassageIDtrue);
  5952.         if(!empty($ref))
  5953.             return true;
  5954.               
  5955.           $ref $this->getRelatedPassages($nPassageID$nLanguageIDtrue);
  5956.         if(!empty($ref))
  5957.             return true;
  5958.                            
  5959.         return $bRet;
  5960.     }
  5961.     
  5962.     function getTranslationData($translationID)
  5963.     {        
  5964.         $sSql "SELECT t.url, t.language_id, w.swedenborgtype as swedenborgtype FROM expositiontranslation t, expositionwork w where t.id = " $translationID " and t.work_id = w.id limit 1";
  5965.   //  echo $sSql;   
  5966.         
  5967.         return $this->getRowData($sSql);
  5968.     }
  5969.     
  5970.     function getPassageData($passageID)
  5971.     {        
  5972.         $sSql "SELECT ordering, swedenborgsection FROM expositionpassage where id = " $passageID " limit 1";
  5973.  //   echo $sSql;   
  5974.         return $this->getRowData($sSql);
  5975.     }
  5976.     
  5977.     function getExplainedStoryListForSearch($locale$sSearchText)
  5978.     {
  5979.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  5980.     
  5981.         $sSql "select * from (select distinct on (id) * from (SELECT bs.id, case when bsl.name is null then bs.name else bsl.name end as name, url, explanationtitle, commentary_url, work_id, case when bs.language_id = " $nLanguageID " then 1 else case when bs.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end as lang_order, book_id, chapter_order, verse_order from vbiblestoryexplained bs left join (select * from biblestory_language where language_id = " $nLanguageID ") as bsl on bs.id = bsl.biblestory_id where ispublic";        
  5982.         $sSql .= " ) as t";        
  5983.         $sSql .= " order by id, lang_order) as t2";
  5984.         
  5985.         if(!empty($sSearchText))
  5986.             $sSql .= " where lower(name) like '%" str_replace("'""''"strtolower($sSearchText)) . "%'";
  5987.             
  5988.         $sSql .= " order by book_id, chapter_order, verse_order";
  5989.     //echo $sSql . "<br>";            
  5990.         return $this->getNativeQueryResults($sSql);
  5991.     } 
  5992.     
  5993.     function setsessionswhenlogin($user_id$user_level$user_lang_id$user_bible_trans_id$audio_rate$request)
  5994.     {                   
  5995.         if($user_lang_id == 0)
  5996.             $user_lang_id '';
  5997.             
  5998.         if($user_bible_trans_id == 0)
  5999.             $user_bible_trans_id '';    
  6000.     
  6001.         $request->getSession()->set('user_id'$user_id); 
  6002.         $request->getSession()->set('user_level'$user_level);
  6003.         $request->getSession()->set('current_language_id'$user_lang_id);
  6004.         $request->getSession()->set('current_bible_translation_id'$user_bible_trans_id);
  6005.         $request->getSession()->set('current_audio_rate'$audio_rate);
  6006.         
  6007.         $bReceive $this->getVerseOfDayStatus($user_id);
  6008.         $request->getSession()->set('user_receive_verse_of_day'$bReceive);
  6009.     }    
  6010.     
  6011.     function getVerseOfDayStatus($user_id)
  6012.     {
  6013.         $sSql1 "select receive_email_by_date FROM \"user\" where \"UserID\" = " $user_id;
  6014.         //echo $sSql1;
  6015.         $bReceive $this->getSingleData($sSql1);
  6016.         return $bReceive;
  6017.     }
  6018.     
  6019.     function getAudioRate($user_id)
  6020.     {
  6021.         $sSql1 "select audio_rate FROM \"user\" where \"UserID\" = " $user_id;
  6022.         //echo $sSql1;
  6023.         $nRet $this->getSingleData($sSql1);
  6024.         return $nRet;
  6025.     }
  6026.         
  6027.     function getShowInfo($showID)
  6028.     {    
  6029.         $sSql "SELECT s.title, e.description, e.location as video_url, e.notice, e.visibilitydefault, e.youtube_id FROM show s, embed e";        
  6030.         $sSql .= " WHERE s.id = " $showID " and s.embed_id = e.id";
  6031.                             
  6032.   //echo $sSql."<br>";   
  6033.            
  6034.           $aRet = array();       
  6035.         $aTemp $this->getNativeQueryResults($sSql);
  6036.         if(count($aTemp) > 0
  6037.             $aRet $aTemp[0];
  6038.             
  6039.         return $aRet;    
  6040.     }
  6041.     
  6042.     function getLanguageIDByShow($show_id)
  6043.     {                
  6044.         $sSql "select e.language_id from show s, embed e where s.id = " $show_id " and s.embed_id = e.id";
  6045.   //   echo $sSql."<br>";   
  6046.            $nRet $this->getSingleData($sSql);  
  6047.         return $nRet;   
  6048.     }
  6049.     
  6050.     function getShowRefs($show_id$request)
  6051.     {        
  6052.            $language_id $this->getLanguageIDByShow($show_id);
  6053.         $bLangStr = ($language_id != null && $language_id != $this->LANGUAGE_ID_ENGLISH);
  6054.               
  6055.         $sBibleStr '(';
  6056.         $nBibleTransID $request->getSession()->get('current_bible_translation_id');
  6057.         if($nBibleTransID != '')        
  6058.                $sBibleStr .= 'case when trans.id = ' $nBibleTransID ' then 1 else ';
  6059.                
  6060.            if($bLangStr)        
  6061.                $sBibleStr .= 'case when trans.language_id = ' $language_id ' then 2 else ';                    
  6062.         $sBibleStr .= 'case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then case when trans.languagedefault then 3 else 4 end end';
  6063.         if($nBibleTransID != '')        
  6064.                $sBibleStr .= ' end';
  6065.                
  6066.            if($bLangStr)        
  6067.                $sBibleStr .= ' end';
  6068.         
  6069.         $sBibleStr .= ')';
  6070.         
  6071.         $sWorkStr '(';                       
  6072.            if($bLangStr)        
  6073.                $sWorkStr .= 'case when trans.language_id = ' $language_id ' then 2 else ';    
  6074.                 
  6075.         $sWorkStr .= 'case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then case when trans.islanguagedefault then 3 else 4 end end';
  6076.                        
  6077.            if($bLangStr)        
  6078.                $sWorkStr .= ' end';    
  6079.         
  6080.         $sWorkStr .= ')';
  6081.                     
  6082.         $sSql "select t3.* from "
  6083.                 ." (select * from (SELECT distinct on (sb.from_verse_id, sb.to_verse_id) cc1.book_id, cb.ordering as book_order, l.name as link_text1, cc1.ordering || (case when sb.from_verse_id is not null then ':' || cv1.ordering else '' end) || (case when sb.from_verse_id is not null and sb.to_verse_id is not null and sb.from_verse_id <> sb.to_verse_id then '-' || cv2.ordering else '' end) as link_text2, true as is_bibleref, '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc1.ordering || '_' || cv1.ordering || (case when sb.from_verse_id <> sb.to_verse_id then '-' || cv2.ordering else '' end) as multilink_text, cc1.ordering as ordering1, case when cv1.ordering is null then 0 else cv1.ordering end as ordering2, " $sBibleStr " as priority_order, cb.url as book_url, trans.url as trans_url, cc1.ordering as chapter_order1, cv1.ordering as verse_order1, cv2.ordering as verse_order2, trans.url as div_url, 0 as passage_order"
  6084.                 ."  FROM show s, embed e, canonicalbiblechapter cc1, canonicalbiblebook cb, biblebook b, bibletranslation trans, show_bibleref sb"
  6085.                 ." left join canonicalbibleverse cv1 on sb.from_verse_id = cv1.id"
  6086.                 ." left join canonicalbibleverse cv2 on sb.to_verse_id = cv2.id"
  6087.                 ." left join (select distinct on (book_id) book_id, name from canonicalbiblebooklanguage where language_id = " $language_id " and not is_abbr order by book_id, is_standard desc) l on sb.book_id = l.book_id"
  6088.                 ." WHERE s.id = " $show_id " and s.embed_id = e.id and sb.show_id = s.id and sb.chapter_id = cc1.id and cc1.book_id = cb.id and sb.book_id = b.canonicalization_id and b.translation_id = trans.id and trans.enabled order by sb.from_verse_id, sb.to_verse_id, priority_order asc, trans.languagedefault desc) as b"  
  6089.                 ." union"
  6090.                 ." select * from (SELECT distinct on (w.id, p.ordering) d.work_id as book_id, w.id as book_order, l.name as link_text1, (case when p.swedenborgsection is not null then p.swedenborgsection else '' end) as link_text2, false as is_bibleref, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "_' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "_' end) || trans.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as multilink_text, p.ordering as ordering1, 1 as ordering2, " $sWorkStr " as priority_order, trans.url as book_url, trans.url as trans_url, 0 as chapter_order1, 0 as verse_order1, 0 as verse_order2, d.url as div_url, p.ordering as passage_order"
  6091.                 ." FROM show s, expositionpassage p, expositiondivision d, expositionwork w, expositiontranslation trans, show_workref sw"
  6092.                 ." left join (select distinct on (work_id) work_id, name from expositionworklanguage where language_id = " $language_id " and not is_abbr order by work_id, otle_default desc, is_standard desc) l on sw.work_id = l.work_id"
  6093.                 ." WHERE s.id = " $show_id " and sw.show_id = s.id and p.id = sw.passage_id and d.id = p.division_id and d.work_id = w.id and w.id = trans.work_id and trans.url is not null and trans.ispublic and w.ispublic order by w.id, p.ordering, priority_order asc, trans.islanguagedefault desc, trans.isoriginal desc) as e";
  6094.                                                       
  6095.                 $sSql .= ") as t3 order by is_bibleref desc, book_order, ordering1, ordering2";
  6096.      //echo $sSql."<br>";   
  6097.            $aRet $this->getNativeQueryResults($sSql);  
  6098.            $aTemp $aRet;
  6099.            $nLen count($aRet);
  6100.            for($i=0;$i<$nLen;$i++)
  6101.            {
  6102.                $bSameBibleChapter false;
  6103.                if($i && $aRet[$i]["book_id"] == $aRet[$i-1]["book_id"] && $aRet[$i]["is_bibleref"] == $aRet[$i-1]["is_bibleref"])
  6104.                {       
  6105.                    if($aRet[$i]["is_bibleref"])
  6106.                    {
  6107.                        if($aRet[$i]["chapter_order1"] == $aRet[$i-1]["chapter_order1"])
  6108.                        {                                          
  6109.                            $bSameBibleChapter true;
  6110.                            if($aRet[$i-1]["ordering2"] != 0)
  6111.                            { 
  6112.                                // The previous ref is a whole chapter ref
  6113.                                $sTempText $aRet[$i]["link_text2"];
  6114.                                $nPosColon strpos($sTempText":");
  6115.                                if($nPosColon !== false)
  6116.                                {
  6117.                                    $sTempText2 substr($sTempText$nPosColon+1);
  6118.                                    $aRet[$i]["link_text"] = $sTempText2;
  6119.                                }    
  6120.                                else
  6121.                                    $aRet[$i]["link_text"] = $sTempText;
  6122.                            }
  6123.                            else
  6124.                            {
  6125.                                $aRet[$i]["link_text"] = $aRet[$i]["link_text2"];
  6126.                            }
  6127.                        }
  6128.                        else
  6129.                        {
  6130.                            $aRet[$i]["link_text"] = $aRet[$i]["link_text2"];
  6131.                        }
  6132.                    }
  6133.                    else
  6134.                    {
  6135.                        $aRet[$i]["link_text"] = $aRet[$i]["link_text2"];
  6136.                    }                   
  6137.                }
  6138.                else
  6139.                {               
  6140.                    $aRet[$i]["link_text"] = $aRet[$i]["link_text1"] . " " $aRet[$i]["link_text2"];
  6141.                }
  6142.                
  6143.                $aRet[$i]["same_chapter"] = $bSameBibleChapter;
  6144.                 
  6145.                $bWorkRefAfterBibleRef = ($i && $aRet[$i]["is_bibleref"] != $aRet[$i-1]["is_bibleref"]);
  6146.                
  6147.                $aRet[$i]["workref_after_bibleref"] = $bWorkRefAfterBibleRef;
  6148.                                                             
  6149.                $aRet[$i]["singlelink"] = '';
  6150.                if($aRet[$i]["is_bibleref"])
  6151.                {                   
  6152.                 if($aTemp[$i]["verse_order2"] != '' && $aTemp[$i]["verse_order1"] != $aTemp[$i]["verse_order2"])
  6153.                    {
  6154.                        $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_verse_range', array(
  6155.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6156.                         'bookUrl' => $aTemp[$i]["book_url"],
  6157.                         'chapterIndex' => $aTemp[$i]["chapter_order1"],
  6158.                         'verseStartIndex' => $aTemp[$i]["verse_order1"],
  6159.                         'verseEndIndex' => $aTemp[$i]["verse_order2"]
  6160.                     )); 
  6161.                 }
  6162.                 else if($aTemp[$i]["verse_order1"] != '')
  6163.                    {
  6164.                        $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_verse', array(
  6165.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6166.                         'bookUrl' => $aTemp[$i]["book_url"],
  6167.                         'chapterIndex' => $aTemp[$i]["chapter_order1"],
  6168.                         'verseIndex' => $aTemp[$i]["verse_order1"]
  6169.                     )); 
  6170.                 }
  6171.                 else
  6172.                 {
  6173.                     $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_chapter', array(
  6174.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6175.                         'bookUrl' => $aTemp[$i]["book_url"],
  6176.                         'chapterIndex' => $aTemp[$i]["chapter_order1"]
  6177.                     ));
  6178.                 }                      
  6179.                }
  6180.                else
  6181.                {
  6182.                    $aRet[$i]["singlelink"] = $this->get('router')->generate('exposition_translation_division_passage', array(
  6183.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6184.                         'divisionUrls' => $aTemp[$i]["div_url"],
  6185.                         'passageNumber' => $aTemp[$i]["passage_order"]
  6186.                     )); 
  6187.                }
  6188.            }
  6189.              
  6190.         return $aRet;  
  6191.     }
  6192.     
  6193.     function getOTLEVideos($nStartNum$request)
  6194.     {        
  6195.         $aRet = array();
  6196.    //     $nMaxResult = 400;
  6197.      //   $nLanguageID = $this->getLanguageIDByShortCode($locale);
  6198.      
  6199.          $searchOptions $request->query->all();
  6200.                  
  6201.         $sSql "SELECT s.id, s.title, e.description, e.youtube_id, case when e.youtube_id is not null and e.youtube_id <> '' then 1 else 2 end as ordering2"
  6202.         $sSql .= " FROM show s, embed e";
  6203.         $sSql .= " where e.visibilitydefault and s.embed_id = e.id and (s.showtype_id in (select id from showtype where public_on_ncbs) or s.showtype_id is null)";  
  6204.                 
  6205.         $nBrandID "";
  6206.         if(array_key_exists('brandid'$searchOptions))
  6207.             $nBrandID $searchOptions['brandid'];
  6208.         
  6209.         $bOffTheLeftEye false;
  6210.         if($nBrandID != '')    
  6211.             $bOffTheLeftEye = ($nBrandID == $this->BRAND_ID_OFF_THE_LEFT_EYE);
  6212.             
  6213.         $nTopicID "";
  6214.         if($bOffTheLeftEye && array_key_exists('topicid'$searchOptions))
  6215.             $nTopicID $searchOptions['topicid'];    
  6216.             
  6217.         $nTypeID "";
  6218.         if($bOffTheLeftEye && array_key_exists('typeid'$searchOptions))
  6219.             $nTypeID $searchOptions['typeid'];        
  6220.         
  6221.         $sFilter "";
  6222.         if($nBrandID != '')
  6223.         {
  6224.              $sFilter .= " and s.brand_id = " $nBrandID;
  6225.              
  6226.              if($nTopicID != '')
  6227.             {
  6228.                  $sFilter .= " and s.id in (select show_id from show_topic where topic_id = " $nTopicID ")";
  6229.             }
  6230.             
  6231.             if($nTypeID != '')
  6232.             {
  6233.                  $sFilter .= " and s.showtype_id = " $nTypeID;
  6234.             }
  6235.         }    
  6236.         else if($nStartNum == -1)
  6237.         {
  6238.             // get featured
  6239.             $sFilter .= " and is_featured";
  6240.         } 
  6241.         
  6242.         $sSql .= $sFilter;            
  6243.                  
  6244.         $sSql .= " order by is_featured desc, ordering2";
  6245.    //     $sSql .= " LIMIT ". $nMaxResult; 
  6246.         if($nStartNum 1)
  6247.         {            
  6248.             $sSql .= " OFFSET " $nStartNum;
  6249.         }   
  6250.              
  6251.     //   echo $sSql . "<br>";  
  6252.           $results $this->getNativeQueryResults($sSql);
  6253.         $aRet['results'] = $results
  6254.         
  6255.  /*       $sSql = 'SELECT count(s.id)'; 
  6256.         $sSql .= ' FROM show s, embed e';
  6257.         $sSql .= ' where e.visibilitydefault and s.embed_id = e.id and (s.showtype_id in (select id from showtype where public_on_ncbs) or s.showtype_id is null)';  
  6258.         
  6259.         $sSql .= $sFilter;    
  6260.         
  6261.         $nTotalNum = $this->getSingleData($sSql); */
  6262.         
  6263.         $nTotalNum count($results);
  6264.     //    $bHasMore = (count($results) >= $nMaxResult);
  6265.         $bHasMore false;
  6266.             
  6267.         $aRet['total_record'] = $nTotalNum;
  6268.         $aRet['has_more'] = $bHasMore;
  6269.         $aRet['start_num'] = $nStartNum;
  6270.         return $aRet;
  6271.     } 
  6272.     
  6273.     function getBrandList()
  6274.     {
  6275.         $sSql "SELECT id, name"
  6276.                 ." FROM brand where id in (select distinct brand_id from show) order by name";
  6277.    // echo $sSql . "<br>";    
  6278.         $aRet $this->getNativeQueryResults($sSql);                        
  6279.         return $aRet;  
  6280.     }  
  6281.     
  6282.     function getShowTopicList()
  6283.     {
  6284.         $sSql "SELECT id, name"
  6285.                 ." FROM showtopic where id in (select distinct topic_id from show_topic) order by name";
  6286.    // echo $sSql . "<br>";    
  6287.         $aRet $this->getNativeQueryResults($sSql);                        
  6288.         return $aRet;  
  6289.     } 
  6290.     
  6291.     function getShowTypeList()
  6292.     {
  6293.         $sSql "SELECT id, name"
  6294.                 ." FROM showtype where public_on_ncbs and id in (select distinct showtype_id from show) order by name";
  6295.    // echo $sSql . "<br>";    
  6296.         $aRet $this->getNativeQueryResults($sSql);                        
  6297.         return $aRet;  
  6298.     }
  6299.     
  6300.     function getLanguageListForAudioHub()
  6301.     {            
  6302.         $sSql "select id, (case when nativename is not null and nativename <> '' then nativename else name end) as name from language where id in (select distinct language_id from expositiontranslation where primaryformat_id = " $this->PRIMARY_FORMAT_ID_AUDIO ")";                
  6303.         $sSql .= " order by name";
  6304. //    echo $sSql . "<br>";            
  6305.         return $this->getNativeQueryResults($sSql);
  6306.     }    
  6307.     
  6308.     function getExplanationList($nStartNum$locale$request$vFormatID=null)
  6309.     {        
  6310.         $nCategoryId $request->query->get('catid');        
  6311.         $nForceLanguageID $request->query->get('language');
  6312.         $nLanguageID $nForceLanguageID;
  6313.         if(empty($nLanguageID))
  6314.             $nLanguageID $this->getLanguageIDByShortCode($locale);
  6315.         
  6316.         $sLangStr '';
  6317.         if($nLanguageID != null)
  6318.         {
  6319.             $sLangStr 'case when t.language_id = ' $nLanguageID ' then 1 else';
  6320.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  6321.                 $sLangStr .= ' case when t.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 2 else';
  6322.                 
  6323.             $sLangStr .= ' 3 end';
  6324.             
  6325.             if($nLanguageID != $this->LANGUAGE_ID_ENGLISH)
  6326.                 $sLangStr .= ' end';
  6327.                 
  6328.             $sLangStr .= ' as language_order';        
  6329.         }
  6330.         else
  6331.             $sLangStr .= '1 as language_order';    
  6332.         
  6333.         $sSql "select * from (SELECT distinct on (w.id) w.id as work_id, t.id as tid,"
  6334.                 ."t.translatedtitle AS title, t.description, t.url, wo.feature_ordering,"
  6335.                 $sLangStr 
  6336.                 ", case when t.islanguagedefault then 1 else 2 end as lang_default_order"
  6337.                 ", case when wo.is_featured then 1 else 2 end as is_featured"
  6338.                 ", case when fi.image_file is null then ti.image_file else fi.image_file end as image_file, case when fi.image_file is null then ti.image_title else fi.image_title end as image_title, t.primaryformat_id, case when t.primaryformat_id = " $this->PRIMARY_FORMAT_ID_VIDEO " then te.youtube_id else null end as youtube_id"
  6339.                 ." FROM expositiontranslation t join expositionwork w on t.work_id = w.id";
  6340.         $sSql .= " left join (select distinct on (t1.id) t1.id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on t.id = fi.id";
  6341.         $sSql .= " left join (select distinct on (tt1.translation_id) tt1.translation_id, i.file as image_file, i.title as image_title from textunit_image ti, image i, expositiontranslationtext tt1 where ti.textunit_id = tt1.placement_id and ti.image_id = i.id and i.mediatype_id = 1";        
  6342.          $sSql .= ") ti on t.id = ti.translation_id";
  6343.          $sSql .= " left join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering, t2.is_featured from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") wo on w.id = wo.work_id"
  6344.          $sSql .= " left join (select distinct on (d.work_id) d.work_id, e.youtube_id from passage_media pm, expositionpassage p, expositiondivision d, embed e";
  6345.         $sSql .= " where e.youtube_id is not null and e.id = pm.embed_id";
  6346.         $sSql .= " and pm.passage_id = p.id and p.division_id = d.id order by d.work_id, p.ordering) te on w.id = te.work_id";
  6347.         $sSql .= " WHERE ";
  6348.      
  6349.         if(!empty($nCategoryId))
  6350.             $sSql .= "(t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $nCategoryId ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $nCategoryId "))";
  6351.         else
  6352.             $sSql .= "(t.work_id IN (SELECT work_id FROM work_category) OR t.id IN (SELECT translation_id FROM translation_category))";
  6353.         
  6354.         if($vFormatID != null)
  6355.             $sSql .= " and t.primaryformat_id = " $vFormatID
  6356.             
  6357.         $sFilter "";
  6358.         if($nForceLanguageID != '')
  6359.         {
  6360.              $sFilter .= " and t.language_id = " $nForceLanguageID;            
  6361.         }    
  6362.   /*      else if($nStartNum == -1)
  6363.         {
  6364.             // get featured
  6365.             $sFilter .= " and (wo.is_featured or image_file is not null)";
  6366.         } */
  6367.         
  6368.         $sSql .= $sFilter;    
  6369.             
  6370.         $sSql .= " and t.type_id = 1"
  6371.         $sSql .= " and t.ispublic AND w.ispublic and t.url is not null and t.url <> ''";         
  6372.         $sSql .= " ORDER BY w.id, is_featured, language_order, lang_default_order) as t where language_order < 3";
  6373.         
  6374.         if(empty($nForceLanguageID) && $nStartNum == -1)
  6375.         {
  6376.             // Featured first, then Newest ones that have images. max of 15.
  6377.             $sSql .= " and (is_featured = 1 or image_file is not null)";
  6378.             $sSql .= " ORDER BY is_featured, tid desc"
  6379.             $sSql .= " limit 15";
  6380.         } 
  6381.         else
  6382.         {
  6383.             $sSql .= " ORDER BY is_featured, (case when image_file is not null and description is not null then 1 else case when image_file is not null then 2 else case when youtube_id is not null then 3 else case when description is not null then 4 else case when title is not null then 5 else 6 end end end end end), feature_ordering, title";   
  6384.         }
  6385.              
  6386.     //    echo $sSql . "<br>";          
  6387.         return $this->getNativeQueryResults($sSql);
  6388.     }
  6389.     
  6390.     function getPrevNextLink($translation_id$category_id$request)
  6391.     {
  6392.         $aRet = array();
  6393.         $locale $request->getLocale();
  6394.         $nUILanguageID $this->getLanguageIDByShortCode($locale);
  6395.         $sPrevUrl null;
  6396.         $sNextUrl null;
  6397.         $sSql "select work_id, language_id from expositiontranslation where id = " $translation_id;
  6398.         $aTrans $this->getRowData($sSql);
  6399.     //    print_r($aTrans);
  6400.         $nWorkID $aTrans['work_id'];
  6401.         $nLangID $aTrans['language_id'];
  6402.         
  6403.         $sLangOrderStr '(case when language_id = ' $nUILanguageID ' then 1 else case when language_id = ' $nLangID ' then 2 else case when language_id = ' $this->LANGUAGE_ID_ENGLISH ' then 3 else 4 end end end )';
  6404.     
  6405.         $sSql "SELECT t.url FROM expositiontranslation t, expositionwork w WHERE ";
  6406.         $sSql .= "(t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $category_id ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $category_id "))";
  6407.         $sSql .= " and t.work_id > " $nWorkID " and t.work_id = w.id and w.ispublic AND t.ispublic order by " $sLangOrderStr ", w.id limit 1";
  6408.            //     echo $sSql."<br>";
  6409.    
  6410.           $sNextUrl $this->getSingleData($sSql);
  6411.           if($sNextUrl == '')
  6412.           {
  6413.               $sSql "SELECT t.url FROM expositiontranslation t, expositionwork w WHERE ";
  6414.             $sSql .= "(t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $category_id ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $category_id "))";
  6415.             $sSql .= " and t.work_id = w.id and w.ispublic AND t.ispublic order by w.id, " $sLangOrderStr ", w.id limit 1";
  6416.    //             echo $sSql."<br>";
  6417.               $sNextUrl $this->getSingleData($sSql); 
  6418.           }
  6419.          $aRet['next'] = $sNextUrl;
  6420.      
  6421.         $sSql "SELECT t.url FROM expositiontranslation t, expositionwork w WHERE ";
  6422.         $sSql .= "(t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $category_id ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $category_id "))";
  6423.         $sSql .= " and t.work_id < " $nWorkID " and t.work_id = w.id and w.ispublic AND t.ispublic order by " $sLangOrderStr ", w.id desc limit 1";
  6424.     //            echo $sSql."<br>";
  6425.          $sPrveUrl $this->getSingleData($sSql);
  6426.           if($sPrveUrl == '')
  6427.           {
  6428.               $sSql "SELECT t.url FROM expositiontranslation t, expositionwork w WHERE ";
  6429.             $sSql .= "(t.work_id IN (SELECT work_id FROM work_category WHERE category_id=" $category_id ") OR t.id IN (SELECT translation_id FROM translation_category WHERE category_id=" $category_id "))";
  6430.             $sSql .= " and t.work_id = w.id and w.ispublic AND t.ispublic order by w.id desc, " $sLangOrderStr ", w.id desc limit 1";
  6431.   //              echo $sSql."<br>";
  6432.               $sPrveUrl $this->getSingleData($sSql); 
  6433.           }
  6434.      
  6435.          $aRet['prev'] = $sPrveUrl;               
  6436.                 
  6437.         return $aRet;         
  6438.     } 
  6439.     
  6440.     function checkCategory($translation_id$category_id)
  6441.     {
  6442.         $sSql "SELECT id FROM expositiontranslation WHERE id = " $translation_id;
  6443.         $sSql .= " and (work_id IN (SELECT work_id FROM work_category WHERE category_id=" $category_id ") OR id IN (SELECT translation_id FROM translation_category WHERE category_id=" $category_id "))";
  6444.         $sSql .= " limit 1";
  6445.     //            echo $sSql."<br>";
  6446.          $nID $this->getSingleData($sSql);
  6447.          return ($nID != '');
  6448.     }
  6449.     
  6450.     function getClassList($nStartNum$request)
  6451.     {        
  6452.         $aRet = array();
  6453.    //     $nMaxResult = 400;
  6454.      //   $nLanguageID = $this->getLanguageIDByShortCode($locale);
  6455.      
  6456.          $searchOptions $request->query->all();
  6457.                  
  6458.         $sSql "SELECT c.id, c.name, c.description, c.class_info_link, i.file as image_file, i.title as image_title"
  6459.         $sSql .= " FROM course c left join image i on c.image_id = i.id";
  6460.         $sSql .= " where c.is_public"
  6461.          
  6462.         $sFilter "";
  6463.                 
  6464.         $nLanguageID "";
  6465.         if(array_key_exists('language'$searchOptions))
  6466.             $nLanguageID $searchOptions['language'];
  6467.         
  6468.         if($nLanguageID != '')
  6469.         {
  6470.              $sFilter .= " and c.language_id = " $nLanguageID;             
  6471.         }    
  6472.         
  6473.   /*      else if($nStartNum == -1)
  6474.         {
  6475.             // get featured
  6476.             // $sFilter .= " and is_featured";
  6477.         } 
  6478.         */
  6479.         
  6480.         $sSql .= $sFilter;            
  6481.                  
  6482.         $sSql .= " order by ordering, id desc";
  6483.    //     $sSql .= " LIMIT ". $nMaxResult; 
  6484.         if($nStartNum 1)
  6485.         {            
  6486.             $sSql .= " OFFSET " $nStartNum;
  6487.         }   
  6488.              
  6489. //       echo $sSql . "<br>";  
  6490.           $results $this->getNativeQueryResults($sSql);
  6491.         $aRet['results'] = $results
  6492.                  
  6493.         $nTotalNum count($results);
  6494.     //    $bHasMore = (count($results) >= $nMaxResult);
  6495.         $bHasMore false;
  6496.         $bHasFilter = ($sFilter != '');           
  6497.         $aRet['total_record'] = $nTotalNum;
  6498.         $aRet['has_more'] = $bHasMore;
  6499.         $aRet['start_num'] = $nStartNum;
  6500.         $aRet['has_filter'] = $bHasFilter;
  6501.         return $aRet;
  6502.     } 
  6503.     
  6504.     function getLanguageListForClassHub()
  6505.     {            
  6506.         $sSql "select id, (case when nativename is not null and nativename <> '' then nativename else name end) as name from language where id in (select distinct language_id from course where language_id is not null and class_info_link is not null and image_id is not null)";                
  6507.         $sSql .= " order by name";
  6508. //    echo $sSql . "<br>";            
  6509.         return $this->getNativeQueryResults($sSql);
  6510.     } 
  6511.     
  6512.     function getCourseInfo($courseID)
  6513.     {    
  6514.         $sDateFormat "Mon dd, yyyy";
  6515.         $sSql "SELECT c.id, c.name, c.description, c.full_description, c.class_info_link, i.file as image_file, i.title as image_title, TO_CHAR(c.start_date:: DATE, '" $sDateFormat "') as start_date, TO_CHAR(c.end_date:: DATE, '" $sDateFormat "') as end_date, c.meeting_time, lt.id as locationtype_id, lt.name as locationtype, c.is_sync, case when locationtype_id = " $this->LOCATIONTYPE_ID_VIRTUAL " then '' else case when c.address is null then '' else c.address end || case when c.city is null then '' else '<br>' || c.city end || case when c.country_id in (237, 37) then case when es.name is null then '' else ', ' || es.name end else case when c.province is null then '' else ', ' || c.province end end || case when c.zip_code is null then '' else ' ' || c.zip_code end || case when ec.name is null then '' else '<br>' || ec.name end end as address"
  6516.         $sSql .= " FROM locationtype lt, course c left join image i on c.image_id = i.id";
  6517.         $sSql .= " left join enumcountry ec on c.country_id = ec.id";
  6518.         $sSql .= " left join enumstate es on c.state_id = es.id";
  6519.         $sSql .= " where c.id = " $courseID " and c.is_public and c.locationtype_id = lt.id";
  6520.                             
  6521.   //echo $sSql."<br>";   
  6522.            
  6523.           $aRet $this->getRowData($sSql);            
  6524.         return $aRet;    
  6525.     }
  6526.     
  6527.     function getLeadersForCourse($course_id)
  6528.     {                                         
  6529.         $sSql "select p.id, ";
  6530.         $sSql .= " case when p.title is null then '' else p.title end";
  6531.         $sSql .= " || case when p.firstname is null then '' else ' ' || p.firstname end";
  6532.         $sSql .= " || case when p.middlename is null then '' else ' ' || p.middlename end";
  6533.         $sSql .= " || case when p.lastname is null then '' else ' ' || p.lastname end";
  6534.         $sSql .= " || case when p.suffix is null then '' else ' ' || p.suffix end as name";
  6535.         $sSql .= " FROM course_person cp, person p";
  6536.         $sSql .= " WHERE cp.course_id = " $course_id " and cp.person_id = p.id";        
  6537.         $sSql .= " order by p.firstname, p.lastname";
  6538.                               
  6539.     // echo $sSql."<br>";
  6540.         $aRet $this->getNativeQueryResults($sSql);         
  6541.            return $aRet;  
  6542.     }
  6543.     
  6544.     function getAudienceForCourse($course_id)
  6545.     {                                         
  6546.         $sSql "select distinct a.id, a.description as name";
  6547.         $sSql .= " FROM course_audience ca, audience a";
  6548.         $sSql .= " WHERE ca.course_id = " $course_id " and ca.audience_id = a.id";        
  6549.         $sSql .= " order by a.description";
  6550.                               
  6551.     // echo $sSql."<br>";
  6552.         $aRet $this->getNativeQueryResults($sSql);         
  6553.            return $aRet;  
  6554.     }
  6555.     
  6556.     function getCategoryListForAudioHub()
  6557.     {            
  6558.         $sSql "select id, name from expositioncategory where id in (select distinct category_id from expositiontranslation t, work_category wc where t.primaryformat_id = " $this->PRIMARY_FORMAT_ID_AUDIO " and t.work_id = wc.work_id)";                
  6559.         $sSql .= " order by name";
  6560. //    echo $sSql . "<br>";            
  6561.         return $this->getNativeQueryResults($sSql);
  6562.     }
  6563.     
  6564.     function getLanguageListForSermonHub()
  6565.     {            
  6566.         $sSql "select id, (case when nativename is not null and nativename <> '' then nativename else name end) as name from language where id in (select distinct language_id from lncsermon where language_id is not null and publish and branch_id = " $this->BRANCH_ID_LNC ")";                
  6567.         $sSql .= " order by name";
  6568. //    echo $sSql . "<br>";            
  6569.         return $this->getNativeQueryResults($sSql);
  6570.     }
  6571.     
  6572.     function getTopicListForSermonHub()
  6573.     {            
  6574.         $sSql "select id, description as name from lnctopic where id in (select distinct topic_id from lncsermon_topic where lncsermon_id in (select id from lncsermon where branch_id = " $this->BRANCH_ID_LNC "))";                
  6575.         $sSql .= " order by name";
  6576. //    echo $sSql . "<br>";            
  6577.         return $this->getNativeQueryResults($sSql);
  6578.     }
  6579.     
  6580.     function getAuthorListForSermonHub()
  6581.     {            
  6582.         $sSql "select id, name from vpersonforcombo where id in (select distinct person_id from lncsermon_person where lncsermon_id in (select id from lncsermon where branch_id = " $this->BRANCH_ID_LNC "))";                
  6583.         $sSql .= " order by name";
  6584. //    echo $sSql . "<br>";            
  6585.         return $this->getNativeQueryResults($sSql);
  6586.     }
  6587.     
  6588.     function getSermonList($nStartNum$request)
  6589.     {        
  6590.         $aRet = array();
  6591.    //     $nMaxResult = 400;
  6592.      //   $nLanguageID = $this->getLanguageIDByShortCode($locale);
  6593.      
  6594.          $searchOptions $request->query->all();
  6595.          
  6596.          // Need to check function getSermonSearchResults in PostgresSearch.php too.        
  6597.         $sSql "SELECT s.id, s.title, s.searchsummary as description, i.file as image_file, i.title as image_title, a.author, case when LOWER(mediaurl) like '%youtube.com%' then replace(mediaurl,'/watch?v=','/embed/') else mediaurl end as mediaurl"
  6598.         $sSql .= " FROM lncsermon s left join image i on s.image_id = i.id";        
  6599.         $sSql .= " left join (select sp.lncsermon_id, array_to_string(array_agg(distinct p.name), ',') as author from person p, lncsermon_person sp where sp.person_id = p.id group by sp.lncsermon_id) as a on s.id = a.lncsermon_id";
  6600.         $sSql .= " where publish"
  6601.         
  6602.         $sFilter "";
  6603.         
  6604.         $sTypeIDs "";
  6605.         $sBranchIDs "";
  6606.         if(array_key_exists('storehouse'$searchOptions))
  6607.             $sTypeIDs $this->LNCSERMON_TYPE_ID_PUBLIC;
  6608.         else
  6609.             $sBranchIDs $this->BRANCH_ID_LNC;    
  6610.                 
  6611.         $nLanguageID "";
  6612.         if(array_key_exists('language'$searchOptions))
  6613.             $nLanguageID $searchOptions['language'];
  6614.             
  6615.         $nTopicID "";
  6616.         if(array_key_exists('topicid'$searchOptions))
  6617.             $nTopicID $searchOptions['topicid'];    
  6618.             
  6619.         $nAuthorID "";
  6620.         if(array_key_exists('authorid'$searchOptions))
  6621.             $nAuthorID $searchOptions['authorid'];    
  6622.             
  6623.         if($sTypeIDs != '')
  6624.         {
  6625.              $sFilter .= " and s.type_id in (" $sTypeIDs ")";             
  6626.         }    
  6627.         
  6628.         if($sBranchIDs != '')
  6629.         {
  6630.              $sFilter .= " and s.branch_id in (" $sBranchIDs ")";             
  6631.         }
  6632.         
  6633.         if($nLanguageID != '')
  6634.         {
  6635.              $sFilter .= " and s.language_id = " $nLanguageID;             
  6636.         }    
  6637.         
  6638.         if($nTopicID != '')
  6639.         {
  6640.              $sFilter .= " and s.id in (select lncsermon_id from lncsermon_topic where topic_id = " $nTopicID ")";             
  6641.         }
  6642.         
  6643.         if($nAuthorID != '')
  6644.         {
  6645.              $sFilter .= " and s.id in (select lncsermon_id from lncsermon_person where person_id = " $nAuthorID ")";             
  6646.         }
  6647.         
  6648.   /*      else if($nStartNum == -1)
  6649.         {
  6650.             // get featured
  6651.             // $sFilter .= " and is_featured";
  6652.         } 
  6653.         */
  6654.                 
  6655.         if($sTypeIDs == '' && !$this->userCanSeeAllSermons($request))
  6656.         {
  6657.             $sFilter .= " and (s.type_id = "$this->LNCSERMON_TYPE_ID_PUBLIC;
  6658.             if($this->userCanSeeLNCSermons($request))
  6659.             {
  6660.                 $sFilter .= " or s.type_id = "$this->LNCSERMON_TYPE_ID_LNC_MEMBER;
  6661.             }
  6662.             $sFilter .= ")";
  6663.         }
  6664.          
  6665.         $sSql .= $sFilter;            
  6666.                  
  6667.         $sSql .= " order by s.isrecommended desc, s.date desc";
  6668.    //     $sSql .= " LIMIT ". $nMaxResult; 
  6669.         if($nStartNum 1)
  6670.         {            
  6671.             $sSql .= " OFFSET " $nStartNum;
  6672.         }   
  6673.              
  6674. //       echo $sSql . "<br>";  
  6675.           $results $this->getNativeQueryResults($sSql);
  6676.         $aRet['results'] = $results
  6677.                  
  6678.         $nTotalNum count($results);
  6679.     //    $bHasMore = (count($results) >= $nMaxResult);
  6680.         $bHasMore false;
  6681.         $bHasFilter = ($sFilter != '');
  6682.             
  6683.         $aRet['total_record'] = $nTotalNum;
  6684.         $aRet['has_more'] = $bHasMore;
  6685.         $aRet['start_num'] = $nStartNum;
  6686.         $aRet['has_filter'] = $bHasFilter;
  6687.         return $aRet;
  6688.     } 
  6689.     
  6690.     function getSermonInfo($sermonID)
  6691.     {    
  6692.         $sDateFormat "Mon dd, yyyy";
  6693.         $sSql "SELECT s.id, s.title, s.searchabletext as full_description, TO_CHAR(s.date:: DATE, '" $sDateFormat "') as date, s.searchsummary, s.publicfile, i.file as image_file, i.title as image_title, case when LOWER(mediaurl) like '%youtube.com%' then replace(mediaurl,'/watch?v=','/embed/') else mediaurl end as mediaurl"
  6694.         $sSql .= " FROM lncsermon s left join image i on s.image_id = i.id";         
  6695.         $sSql .= " where s.id = " $sermonID;
  6696.         
  6697.   //echo $sSql."<br>";   
  6698.            
  6699.           $aRet $this->getRowData($sSql);
  6700.           $sMediaUrl $aRet['mediaurl'];
  6701.           $youtube_id $this->getYoutubeID($sMediaUrl);
  6702.           $aRet['youtube_id'] = $youtube_id;
  6703.         return $aRet;    
  6704.     }
  6705.     
  6706.     function getSermonTypeID($sermonID)
  6707.     {            
  6708.         $sSql "SELECT type_id"
  6709.         $sSql .= " FROM lncsermon";         
  6710.         $sSql .= " where id = " $sermonID;
  6711.                             
  6712.   //echo $sSql."<br>";   
  6713.            
  6714.           $nRet $this->getSingleData($sSql);            
  6715.         return $nRet;    
  6716.     }
  6717.     
  6718.     function getAuthorsForSermon($sermonID)
  6719.     {                                         
  6720.         $sSql "select p.id, ";
  6721.         $sSql .= " case when p.title is null then '' else p.title end";
  6722.         $sSql .= " || case when p.firstname is null then '' else ' ' || p.firstname end";
  6723.         $sSql .= " || case when p.middlename is null then '' else ' ' || p.middlename end";
  6724.         $sSql .= " || case when p.lastname is null then '' else ' ' || p.lastname end";
  6725.         $sSql .= " || case when p.suffix is null then '' else ' ' || p.suffix end as name";
  6726.         $sSql .= " FROM lncsermon_person sp, person p";
  6727.         $sSql .= " WHERE sp.lncsermon_id = " $sermonID " and sp.person_id = p.id"
  6728.         $sSql .= " order by p.firstname, p.lastname";
  6729.                               
  6730.     // echo $sSql."<br>";
  6731.         $aRet $this->getNativeQueryResults($sSql);         
  6732.            return $aRet;  
  6733.     }
  6734.     
  6735.     function getTopicsForSermon($sermonID)
  6736.     {                                         
  6737.         $sSql "select distinct t.id, t.description as name";
  6738.         $sSql .= " FROM lncsermon_topic st, topic t";
  6739.         $sSql .= " WHERE st.lncsermon_id = " $sermonID " and st.topic_id = t.id";        
  6740.         $sSql .= " order by t.description";
  6741.                               
  6742.     // echo $sSql."<br>";
  6743.         $aRet $this->getNativeQueryResults($sSql);         
  6744.            return $aRet;  
  6745.     }
  6746.     
  6747.     function getLanguageIDBySermon($sermon_id)
  6748.     {                
  6749.         $sSql "select language_id from lncsermon s where s.id = " $sermon_id;
  6750.   //   echo $sSql."<br>";   
  6751.            $nRet $this->getSingleData($sSql);  
  6752.         return $nRet;   
  6753.     }
  6754.     
  6755.     function getSermonRefs($sermon_id$request)
  6756.     {        
  6757.            $language_id $this->getLanguageIDBySermon($sermon_id);
  6758.         $bLangStr = ($language_id != null && $language_id != $this->LANGUAGE_ID_ENGLISH);
  6759.               
  6760.         $sBibleStr '(';
  6761.         $nBibleTransID $request->getSession()->get('current_bible_translation_id');
  6762.         if($nBibleTransID != '')        
  6763.                $sBibleStr .= 'case when trans.id = ' $nBibleTransID ' then 1 else ';
  6764.                
  6765.            if($bLangStr)        
  6766.                $sBibleStr .= 'case when trans.language_id = ' $language_id ' then 2 else ';                    
  6767.         $sBibleStr .= 'case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then case when trans.languagedefault then 3 else 4 end end';
  6768.         if($nBibleTransID != '')        
  6769.                $sBibleStr .= ' end';
  6770.                
  6771.            if($bLangStr)        
  6772.                $sBibleStr .= ' end';
  6773.         
  6774.         $sBibleStr .= ')';
  6775.         
  6776.         $sWorkStr '(';                       
  6777.            if($bLangStr)        
  6778.                $sWorkStr .= 'case when trans.language_id = ' $language_id ' then 2 else ';    
  6779.                 
  6780.         $sWorkStr .= 'case when trans.language_id = ' $this->LANGUAGE_ID_ENGLISH ' then case when trans.islanguagedefault then 3 else 4 end end';
  6781.                        
  6782.            if($bLangStr)        
  6783.                $sWorkStr .= ' end';    
  6784.         
  6785.         $sWorkStr .= ')';
  6786.                     
  6787.         $sSql "select t3.* from "
  6788.                 ." (select * from (SELECT distinct on (sb.from_verse_id, sb.to_verse_id) cc1.book_id, cb.ordering as book_order, l.name as link_text1, cc1.ordering || (case when sb.from_verse_id is not null then ':' || cv1.ordering else '' end) || (case when sb.from_verse_id is not null and sb.to_verse_id is not null and sb.from_verse_id <> sb.to_verse_id then '-' || cv2.ordering else '' end) as link_text2, true as is_bibleref, '" $this->MULTI_URL_INDICATOR_BIBLE "_' || trans.url || '_' || cb.url || '_' || cc1.ordering || '_' || cv1.ordering || (case when sb.from_verse_id <> sb.to_verse_id then '-' || cv2.ordering else '' end) as multilink_text, cc1.ordering as ordering1, case when cv1.ordering is null then 0 else cv1.ordering end as ordering2, " $sBibleStr " as priority_order, cb.url as book_url, trans.url as trans_url, cc1.ordering as chapter_order1, cv1.ordering as verse_order1, cv2.ordering as verse_order2, trans.url as div_url, 0 as passage_order"
  6789.                 ."  FROM lncsermon s, canonicalbiblechapter cc1, canonicalbiblebook cb, biblebook b, bibletranslation trans, lncsermon_bibleref sb"
  6790.                 ." left join canonicalbibleverse cv1 on sb.from_verse_id = cv1.id"
  6791.                 ." left join canonicalbibleverse cv2 on sb.to_verse_id = cv2.id"
  6792.                 ." left join (select distinct on (book_id) book_id, name from canonicalbiblebooklanguage where language_id = " $language_id " and not is_abbr order by book_id, is_standard desc) l on sb.book_id = l.book_id"
  6793.                 ." WHERE s.id = " $sermon_id " and sb.lncsermon_id = s.id and sb.chapter_id = cc1.id and cc1.book_id = cb.id and sb.book_id = b.canonicalization_id and b.translation_id = trans.id and trans.enabled order by sb.from_verse_id, sb.to_verse_id, priority_order asc, trans.languagedefault desc) as b"  
  6794.                 ." union"
  6795.                 ." select * from (SELECT distinct on (w.id, p.ordering) d.work_id as book_id, w.id as book_order, l.name as link_text1, (case when p.swedenborgsection is not null then p.swedenborgsection else '' end) || (case when sw.to_passage_id is not null then '-' || p2.swedenborgsection else '' end) as link_text2, false as is_bibleref, (case when w.swedenborgtype is not null then '" $this->MULTI_URL_INDICATOR_SWEDENBORG_WORK "_' else '" $this->MULTI_URL_INDICATOR_EXPLANATION "_' end) || trans.url || (case when p.swedenborgsection is not null then '_' || p.swedenborgsection else '' end) as multilink_text, p.ordering as ordering1, 1 as ordering2, " $sWorkStr " as priority_order, trans.url as book_url, trans.url as trans_url, 0 as chapter_order1, 0 as verse_order1, 0 as verse_order2, d.url as div_url, p.ordering as passage_order"
  6796.                 ." FROM lncsermon s, expositionpassage p, expositiondivision d, expositionwork w, expositiontranslation trans, lncsermon_workref sw"
  6797.                 ." left join (select distinct on (work_id) work_id, name from expositionworklanguage where language_id = " $language_id " and not is_abbr order by work_id, otle_default desc, is_standard desc) l on sw.work_id = l.work_id"
  6798.                 ." left join expositionpassage p2 on sw.to_passage_id = p2.id"
  6799.                 ." WHERE s.id = " $sermon_id " and sw.lncsermon_id = s.id and p.id = sw.passage_id and d.id = p.division_id and d.work_id = w.id and w.id = trans.work_id and trans.url is not null and trans.ispublic and w.ispublic order by w.id, p.ordering, priority_order asc, trans.islanguagedefault desc, trans.isoriginal desc) as e";
  6800.                                                       
  6801.                 $sSql .= ") as t3 order by is_bibleref desc, book_order, ordering1, ordering2";
  6802.      //echo $sSql."<br>";   
  6803.            $aRet $this->getNativeQueryResults($sSql);  
  6804.            $aTemp $aRet;
  6805.            $nLen count($aRet);
  6806.            for($i=0;$i<$nLen;$i++)
  6807.            {
  6808.                $bSameBibleChapter false;
  6809.                if($i && $aRet[$i]["book_id"] == $aRet[$i-1]["book_id"] && $aRet[$i]["is_bibleref"] == $aRet[$i-1]["is_bibleref"])
  6810.                {       
  6811.                    if($aRet[$i]["is_bibleref"])
  6812.                    {
  6813.                        if($aRet[$i]["chapter_order1"] == $aRet[$i-1]["chapter_order1"])
  6814.                        {                                          
  6815.                            $bSameBibleChapter true;
  6816.                            if($aRet[$i-1]["ordering2"] != 0)
  6817.                            { 
  6818.                                // The previous ref is a whole chapter ref
  6819.                                $sTempText $aRet[$i]["link_text2"];
  6820.                                $nPosColon strpos($sTempText":");
  6821.                                if($nPosColon !== false)
  6822.                                {
  6823.                                    $sTempText2 substr($sTempText$nPosColon+1);
  6824.                                    $aRet[$i]["link_text"] = $sTempText2;
  6825.                                }    
  6826.                                else
  6827.                                    $aRet[$i]["link_text"] = $sTempText;
  6828.                            }
  6829.                            else
  6830.                            {
  6831.                                $aRet[$i]["link_text"] = $aRet[$i]["link_text2"];
  6832.                            }
  6833.                        }
  6834.                        else
  6835.                        {
  6836.                            $aRet[$i]["link_text"] = $aRet[$i]["link_text2"];
  6837.                        }
  6838.                    }
  6839.                    else
  6840.                    {
  6841.                        $aRet[$i]["link_text"] = $aRet[$i]["link_text2"];
  6842.                    }                   
  6843.                }
  6844.                else
  6845.                {               
  6846.                    $aRet[$i]["link_text"] = $aRet[$i]["link_text1"] . " " $aRet[$i]["link_text2"];
  6847.                }
  6848.                
  6849.                $aRet[$i]["same_chapter"] = $bSameBibleChapter;
  6850.                 
  6851.                $bWorkRefAfterBibleRef = ($i && $aRet[$i]["is_bibleref"] != $aRet[$i-1]["is_bibleref"]);
  6852.                
  6853.                $aRet[$i]["workref_after_bibleref"] = $bWorkRefAfterBibleRef;
  6854.                                                             
  6855.                $aRet[$i]["singlelink"] = '';
  6856.                if($aRet[$i]["is_bibleref"])
  6857.                {                   
  6858.                 if($aTemp[$i]["verse_order2"] != '' && $aTemp[$i]["verse_order1"] != $aTemp[$i]["verse_order2"])
  6859.                    {
  6860.                        $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_verse_range', array(
  6861.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6862.                         'bookUrl' => $aTemp[$i]["book_url"],
  6863.                         'chapterIndex' => $aTemp[$i]["chapter_order1"],
  6864.                         'verseStartIndex' => $aTemp[$i]["verse_order1"],
  6865.                         'verseEndIndex' => $aTemp[$i]["verse_order2"]
  6866.                     )); 
  6867.                 }
  6868.                 else if($aTemp[$i]["verse_order1"] != '')
  6869.                    {
  6870.                        $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_verse', array(
  6871.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6872.                         'bookUrl' => $aTemp[$i]["book_url"],
  6873.                         'chapterIndex' => $aTemp[$i]["chapter_order1"],
  6874.                         'verseIndex' => $aTemp[$i]["verse_order1"]
  6875.                     )); 
  6876.                 }
  6877.                 else
  6878.                 {
  6879.                     $aRet[$i]["singlelink"] = $this->get('router')->generate('bible_chapter', array(
  6880.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6881.                         'bookUrl' => $aTemp[$i]["book_url"],
  6882.                         'chapterIndex' => $aTemp[$i]["chapter_order1"]
  6883.                     ));
  6884.                 }                      
  6885.                }
  6886.                else
  6887.                {
  6888.                    $aRet[$i]["singlelink"] = $this->get('router')->generate('exposition_translation_division_passage', array(
  6889.                         'translationUrl' => $aTemp[$i]["trans_url"],
  6890.                         'divisionUrls' => $aTemp[$i]["div_url"],
  6891.                         'passageNumber' => $aTemp[$i]["passage_order"]
  6892.                     )); 
  6893.                }
  6894.            }
  6895.              
  6896.         return $aRet;  
  6897.     }
  6898.         
  6899.     function userCanSeeAllSermons($request)
  6900.     {
  6901.         $nUserLevelID $this->getCurrUserLevel($request);
  6902.         $bRet = ($nUserLevelID == $this->USER_LEVEL_ID_ADMIN || $nUserLevelID == $this->USER_LEVEL_ID_APPLICATION_MANAGER || $nUserLevelID == $this->USER_LEVEL_ID_LNC_ADMIN);
  6903.         return $bRet
  6904.     } 
  6905.     
  6906.     function userCanSeeLNCSermons($request)
  6907.     {
  6908.         $nUserLevelID $this->getCurrUserLevel($request);
  6909.         $bRet = ($nUserLevelID == $this->USER_LEVEL_ID_LNC_MEMBER_WEB_USER);
  6910.         return $bRet
  6911.     }
  6912.     
  6913.     function getBibleBookSummary($translationUrl$bookUrl)
  6914.     {        
  6915.         $sSql "select url from (SELECT t.url, case when bt.language_id = t.language_id then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end as lang_order";                         
  6916.         $sSql .= " FROM expositionwork w, expositiontranslation t, bibletranslation bt, biblebook b, canonicalbiblebook cb where cb.url = '" trim(str_replace("'""''"$bookUrl)) . "' and bt.url = '" trim(str_replace("'""''"$translationUrl)) . "' and cb.id = w.book_id and t.work_id = w.id and w.ispublic AND t.ispublic and b.canonicalization_id = cb.id and b.translation_id = bt.id) as t where lang_order < 3 order by lang_order limit 1"
  6917.     
  6918.  //   echo $sSql."<br>";   
  6919.         return $this->getSingleData($sSql);   
  6920.     }
  6921.     
  6922.     function getBibleBookIDForSummary($translation_id)
  6923.     {        
  6924.         $sSql "SELECT w.book_id";                         
  6925.         $sSql .= " FROM expositionwork w, expositiontranslation t where t.id = " $translation_id " and t.work_id = w.id limit 1"
  6926.     
  6927.   //  echo $sSql."<br>";   
  6928.         return $this->getSingleData($sSql);   
  6929.     }
  6930.     
  6931.     function getBibleBookSummaryList($vBibleBookIDForSummary)
  6932.     {                        
  6933.         $sSql "SELECT distinct t.id as translation_id, t.translatedtitle as explanationtitle, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end as lang_order, w.id as work_id, t.language_id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name "
  6934.                 ." FROM expositionwork w, expositiontranslation t, language l"
  6935.                 ." WHERE w.book_id = " $vBibleBookIDForSummary
  6936.                 ." and t.work_id=w.id and t.language_id = l.id"
  6937.                 ." and w.ispublic AND t.ispublic order by lang_order";
  6938.         
  6939.   //      echo $sSql."<br>"; 
  6940.         
  6941.         return $this->getNativeQueryResults($sSql);
  6942.     }  
  6943.     
  6944.     function getUIStrings($request)
  6945.     {                
  6946.         $aRet = array();
  6947.         $locale $request->getLocale();
  6948.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  6949.         $aStringLang $request->getSession()->get('ui_string_lang');
  6950.         $aDateMod $request->getSession()->get('ui_string_date_mod');
  6951.         $bCheckDB false;
  6952.         $bCheckDB = (empty($aStringLang) || !array_key_exists($nLanguageID$aStringLang));
  6953.         
  6954.         $sSql1 "SELECT max(sl.datemod)"
  6955.                 ." FROM ui_string_language sl, ui_string s"
  6956.                 ." WHERE sl.language_id in (" $nLanguageID ", " $this->LANGUAGE_ID_ENGLISH ")"
  6957.                 ." and s.id = sl.ui_string_id and s.is_active and s.type_id in (1, 3)";
  6958.                     
  6959.         $sDateMod $this->getSingleData($sSql1);
  6960.     
  6961.         if(!$bCheckDB)
  6962.         {
  6963.             //$sLastDateMod = $request->getSession()->get('ui_string_date_mod');    
  6964.             $bCheckDB = (empty($aDateMod) || !array_key_exists($nLanguageID$aDateMod)); 
  6965.             if(!$bCheckDB)
  6966.             {
  6967.                 $bCheckDB = ($sDateMod != $aDateMod[$nLanguageID]);
  6968.             }
  6969.         }
  6970.         
  6971.         $aDateMod[$nLanguageID] = $sDateMod;
  6972.         $request->getSession()->set('ui_string_date_mod'$aDateMod);
  6973.             
  6974.         if($bCheckDB)
  6975.         {        
  6976.             $sSql "";    
  6977.             if($nLanguageID == $this->LANGUAGE_ID_ENGLISH)
  6978.             {    
  6979.                 $sSql "SELECT distinct s.name, sl.text, s.fix_quote"
  6980.                     ." FROM ui_string_language sl, ui_string s"
  6981.                     ." WHERE sl.language_id = " $nLanguageID " and s.id = sl.ui_string_id";
  6982.             }
  6983.             else
  6984.             {
  6985.                 $sSql "SELECT distinct s.name, case when sl2.id is null then sl.text else sl2.text end as text, s.fix_quote"
  6986.                     ." FROM (select * from ui_string_language where language_id = " $this->LANGUAGE_ID_ENGLISH ") sl, ui_string s"
  6987.                     ." left join (select * from ui_string_language where language_id = " $nLanguageID " and text is not null and text <> '') sl2 on s.id = sl2.ui_string_id where s.id = sl.ui_string_id";
  6988.             } 
  6989.             
  6990.             $sSql .= " and s.is_active and s.type_id in (1, 3)";
  6991.             
  6992.       //     echo $sSql."<br>";               
  6993.             $aTemp $this->getNativeQueryResults($sSql);   
  6994.             foreach($aTemp as $t)
  6995.             {
  6996.                 $sCurrText trim($t['text']);
  6997.                 if($t['fix_quote'])
  6998.                     $sCurrText str_replace('\\\\"','\\"'str_replace('"','\\"'$sCurrText));
  6999.                 
  7000.                 $aRet[$t['name']] = $sCurrText;
  7001.             }
  7002.             
  7003.             $request->getSession()->set('ui_str'$aRet);
  7004.             $aStringLang[$nLanguageID] = $aRet;
  7005.             $request->getSession()->set('ui_string_lang'$aStringLang);
  7006.         }
  7007.         else
  7008.         {
  7009.             //$aRet = $request->getSession()->get('ui_str');
  7010.             $aRet $aStringLang[$nLanguageID];
  7011.             $request->getSession()->set('ui_str'$aRet);
  7012.         //    echo "languageID: ".$nLanguageID."<br>";
  7013.         //    print_r($aRet);
  7014.         }
  7015.         
  7016.         return $aRet;
  7017.     } 
  7018.     
  7019.     function onloadPage($request)
  7020.     {
  7021.         $this->getUIStrings($request);
  7022.     }
  7023.     
  7024.     function getYmlData($vYml)
  7025.     {
  7026.         //print_r($vYml);
  7027.         foreach($vYml as $key=>$item)
  7028.         {
  7029.             $sName $key;
  7030.             $sText "";
  7031.             foreach($item as $key2=>$item2)
  7032.             {
  7033.                 $sName2 $sName.".".$key2;
  7034.                 if (is_array($item2))
  7035.                 {                    
  7036.                     foreach($item2 as $key3=>$item3)
  7037.                     {        
  7038.                         $sName3 $sName2.".".$key3;                
  7039.                         if (is_array($item3))
  7040.                         {                            
  7041.                             foreach($item3 as $key4=>$item4)
  7042.                             {
  7043.                                 $sName4 $sName3.".".$key4;
  7044.                                 if (is_array($item4))
  7045.                                 {                                    
  7046.                                     foreach($item4 as $key5=>$item5)
  7047.                                     {
  7048.                                         $sName5 $sName4.".".$key5;
  7049.                                         if (is_array($item5))
  7050.                                         {                                    
  7051.                                             foreach($item5 as $key6=>$item6)
  7052.                                             {
  7053.                                                 $sText $item6;
  7054.                                                 $sCurrName $sName5 "." $key6;
  7055.                                                 echo $sCurrName "^f^" $sText "~|~";
  7056.                                             }
  7057.                                         }
  7058.                                         else
  7059.                                         {
  7060.                                             $sText $item5;
  7061.                                             //$sCurrName = $sName5 . "." . $key5;
  7062.                                             echo $sName5 "^f^" $sText "~|~";
  7063.                                         }                                        
  7064.                                     }
  7065.                                 }
  7066.                                 else
  7067.                                 {
  7068.                                     $sText $item4;
  7069.                                 //    $sCurrName = $sName4 . "." . $key4;
  7070.                                     echo $sName4 "^f^" $sText "~|~";
  7071.                                 }
  7072.                             }
  7073.                         }
  7074.                         else
  7075.                         {
  7076.                             $sText $item3;
  7077.                             //$sCurrName = $sName3 . "." . $key3;
  7078.                             echo $sName3 "^f^" $sText "~|~";
  7079.                         }
  7080.                     }
  7081.                 }
  7082.                 else
  7083.                 {
  7084.                     $sText $item2;
  7085.                 //    $sCurrName = $sName2 . "." . $key2;
  7086.                     echo $sName2 "^f^" $sText "~|~";
  7087.                 }
  7088.             }
  7089.         }
  7090.     }  
  7091.     
  7092.     function ui_string_replace($ui_string$replace_array)
  7093.     {
  7094.         return str_replace(array_keys($replace_array), array_values($replace_array), $ui_string);
  7095.     }  
  7096.     
  7097.     function getWorkTranslationsByLanguage($work_id$language_id=null)
  7098.     {   
  7099.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as group_name, t.name, t.translatedtitle, (case when b.datecreated is null then '' else ' (' || b.datecreated || ')' end) as datestr, t.url, (case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else case when l.id = " $this->LANGUAGE_ID_LATIN " then 2 else 3 end end) as group_order, l.righttoleft, w.title as work_title, t.isoriginal, t.language_id"
  7100.                 ." FROM language l, expositionwork w, expositiontranslation t left join (select tb.translation_id, b.datecreated from bibliographicdata b, translation_bibliographicdata tb where b.id = tb.bibliographicdata_id) as b on t.id = b.translation_id"
  7101.                 ." WHERE w.id = " $work_id " and w.ispublic and t.work_id = w.id"
  7102.                 ." and t.ispublic and t.language_id = l.id"               
  7103.                 ." AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;  
  7104.                 
  7105.        if(!empty($language_id))
  7106.               $sSql .= " and t.language_id in (" $language_id ")";        
  7107.                 
  7108.        $sSql .= " order by group_order, group_name, t.name";
  7109.   //   echo $sSql."<br>";   
  7110.           
  7111.          $aRet $this->getNativeQueryResults($sSql);
  7112.            $nLen count($aRet);
  7113.            for($i=0;$i<$nLen;$i++)
  7114.            {
  7115.                $sTransName $aRet[$i]['name'];
  7116.                $sTranslatedTitle $aRet[$i]['translatedtitle'];
  7117.                $sWorkTitle $aRet[$i]['work_title'];
  7118.                $sDateStr $aRet[$i]['datestr'];
  7119.                $bOriginal $aRet[$i]['isoriginal'];
  7120.                $nLanguageID $aRet[$i]['language_id'];
  7121.                $sIdentifier $this->convertWorkTransIdentifier($sTransName$sTranslatedTitle$sWorkTitle$sDateStr$bOriginal$nLanguageID);
  7122.                $aRet[$i]["identifier"] = $sIdentifier;
  7123.            }
  7124.            return $aRet;  
  7125.     }
  7126.     
  7127.     function getWorkTranslationsByLanguageAllType($work_id)
  7128.     {   
  7129.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as group_name, t.name, t.translatedtitle, (case when b.datecreated is null then '' else ' (' || b.datecreated || ')' end) as datestr, t.url, (case when l.id = " $this->LANGUAGE_ID_ENGLISH " then 1 else case when l.id = " $this->LANGUAGE_ID_LATIN " then 2 else 3 end end) as group_order, l.righttoleft, w.title as work_title, t.isoriginal, t.type_id, t.public_file, t.language_id"
  7130.                 ." FROM language l, expositionwork w, expositiontranslation t left join (select tb.translation_id, b.datecreated from bibliographicdata b, translation_bibliographicdata tb where b.id = tb.bibliographicdata_id) as b on t.id = b.translation_id"
  7131.                 ." WHERE w.id = " $work_id " and w.ispublic and t.work_id = w.id"
  7132.                 ." and t.ispublic and t.language_id = l.id";                           
  7133.        $sSql .= " order by group_order, group_name, t.name";
  7134.   //   echo $sSql."<br>";   
  7135.           
  7136.          $aRet $this->getNativeQueryResults($sSql);
  7137.            $nLen count($aRet);
  7138.            for($i=0;$i<$nLen;$i++)
  7139.            {
  7140.                $sTransName $aRet[$i]['name'];
  7141.                $sTranslatedTitle $aRet[$i]['translatedtitle'];
  7142.                $sWorkTitle $aRet[$i]['work_title'];
  7143.                $sDateStr $aRet[$i]['datestr'];
  7144.                $bOriginal $aRet[$i]['isoriginal'];
  7145.                $nLanguageID $aRet[$i]['language_id'];
  7146.                $sIdentifier $this->convertWorkTransIdentifier($sTransName$sTranslatedTitle$sWorkTitle$sDateStr$bOriginal$nLanguageID);
  7147.                $aRet[$i]["identifier"] = $sIdentifier;
  7148.            }
  7149.            return $aRet;  
  7150.     }
  7151.     
  7152.     function getWorkTranslationShortName($vTranslationID)
  7153.     {
  7154.         $sRet "";
  7155.         $sSql "SELECT t.name, t.translatedtitle, (case when b.datecreated is null then '' else ' (' || b.datecreated || ')' end) as datestr, w.title as work_title, t.isoriginal, t.language_id"
  7156.             ." FROM language l, expositionwork w, expositiontranslation t left join (select tb.translation_id, b.datecreated from bibliographicdata b, translation_bibliographicdata tb where b.id = tb.bibliographicdata_id) as b on t.id = b.translation_id"
  7157.             ." WHERE t.id = " $vTranslationID " and t.work_id = w.id"
  7158.             ." and t.language_id = l.id";
  7159.             
  7160.         $aData = array();
  7161.         $aTemp $this->getNativeQueryResults($sSql);
  7162.         if(count($aTemp) > 0
  7163.         {
  7164.             $aData $aTemp[0]; 
  7165.             $sTransName $aData['name'];
  7166.             $sTranslatedTitle $aData['translatedtitle'];
  7167.             $sWorkTitle $aData['work_title'];
  7168.             $sDateStr $aData['datestr'];
  7169.             $bOriginal $aData['isoriginal'];
  7170.             $nLanguageID $aData['language_id'];
  7171.             $sRet $this->convertWorkTransIdentifier($sTransName$sTranslatedTitle$sWorkTitle$sDateStr$bOriginal$nLanguageID);
  7172.         }
  7173.         
  7174.         return $sRet;       
  7175.     }
  7176.     
  7177.     function convertWorkTransIdentifier($vTransName$vTranslatedTitle$vWorkTitle$vDateStr$vOriginal$vLanguageID)
  7178.     {
  7179.         $identifier $vTransName;        
  7180.         // Take out the work title if it appears
  7181.         $identifier str_ireplace(array($vTranslatedTitle$vWorkTitle), ""$identifier);
  7182.         
  7183.         if($vLanguageID == $this->LANGUAGE_ID_ENGLISH && $identifier == $vTransName)
  7184.         {
  7185.             $sTempTitle str_replace("The """$vTranslatedTitle);
  7186.             if($sTempTitle != $vTranslatedTitle)
  7187.             {
  7188.                 $identifier str_ireplace($sTempTitle""$identifier);
  7189.             }
  7190.         }
  7191.         
  7192.         // Take out the word "translation"
  7193.         $sTranslationUIStr $this->getTranslationUIStr($vLanguageID);
  7194.         if(!empty($sTranslationUIStr))
  7195.             $identifier str_ireplace($sTranslationUIStr""$identifier);
  7196.             
  7197.         // Remove whitespace and various kinds of enclosing characters from the ends
  7198.         $identifier trim($identifier" \t\n\r\0\x0B()[]{}<>\"'");
  7199.         if(empty($identifier) && $vOriginal)
  7200.             $identifier 'original' $vDateStr;
  7201.         else
  7202.             $identifier .= $vDateStr;
  7203.             
  7204.         if(trim($identifier) == '')
  7205.             $identifier $vTransName;
  7206.         else
  7207.         {
  7208.             if(strpos($identifier"(") !== false && strpos($identifier")") === false)
  7209.                 $identifier .= ")";
  7210.         }    
  7211.         
  7212.         return $identifier;
  7213.     }
  7214.     
  7215.     function getTranslationUIStr($vLanguageID)
  7216.     {
  7217.         $sSql1 "select text from ui_string_language where ui_string_id = 469 and language_id = " $vLanguageID;
  7218.         //echo $sSql1;
  7219.         $sRet $this->getSingleData($sSql1);
  7220.         $sRet trim(str_replace(":"""$sRet));
  7221.         return $sRet;
  7222.     }
  7223.     
  7224.     function getPrevNextLinkFromList($translation_id$aList)
  7225.     {    
  7226.         $aRet = array();
  7227.         $sPrveUrl '';
  7228.         $sNextUrl '';
  7229.         $bCurrWork false;    
  7230.     
  7231.         foreach($aList as $d)            
  7232.         {          
  7233.               if ($translation_id == $d['translation_id'])          
  7234.               $bCurrWork true;
  7235.             else
  7236.             {
  7237.                 if(!$bCurrWork)
  7238.                 {
  7239.                     $sPrveUrl $d['translation_url'];
  7240.                 }
  7241.                 else
  7242.                 {
  7243.                     $sNextUrl =  $d['translation_url'];    
  7244.                     break;
  7245.                 }    
  7246.             }
  7247.         }  
  7248.         
  7249.         $aRet['prev'] = $sPrveUrl
  7250.         $aRet['next'] = $sNextUrl
  7251.         return $aRet
  7252.     }    
  7253.     
  7254.     function getLanguageIDByBibleTrans($sBibleTranslationUrl)
  7255.     {
  7256.         $sSql1 "select language_id from bibletranslation where url = '" str_replace("'""''"$sBibleTranslationUrl) . "'";
  7257.         //echo $sSql1;
  7258.         $nBookLanguageID $this->getSingleData($sSql1);
  7259.         return $nBookLanguageID;
  7260.     }
  7261.     
  7262.     function showBibleChapterSummary($vLanguageID)
  7263.     {        
  7264.         $bRet true;
  7265.         if(!empty($vLanguageID))
  7266.         {
  7267.             $sSql1 "select show_bible_chapter_summary from language where id = " $vLanguageID;
  7268.             //echo $sSql1;
  7269.             $bRet $this->getSingleData($sSql1);
  7270.         }
  7271.         return $bRet;   
  7272.     }
  7273.     
  7274.     function showBibleHighlights($vLanguageID)
  7275.     {        
  7276.         $bRet true;
  7277.         if(!empty($vLanguageID))
  7278.         {
  7279.             $sSql1 "select show_bible_verse_highlights from language where id = " $vLanguageID;
  7280.             //echo $sSql1;
  7281.             $bRet $this->getSingleData($sSql1);
  7282.         }
  7283.         return $bRet;        
  7284.     }
  7285.     
  7286.     function isSwedenborg($vTranslationID)
  7287.     {        
  7288.         $bRet false;
  7289.         if(!empty($vTranslationID))
  7290.         {
  7291.             $sSql1 "select case when w.swedenborgtype is null then false else true end as sw from expositionwork w, expositiontranslation t where t.id = " $vTranslationID " and t.work_id = w.id";
  7292.             //echo $sSql1;
  7293.             $bRet $this->getSingleData($sSql1);
  7294.         }
  7295.         return $bRet;        
  7296.     }
  7297.     
  7298.     function getStoryInfo($vTranslationID)
  7299.     {        
  7300.         $aRet = array();
  7301.         if(!empty($vTranslationID))
  7302.         {
  7303.             $sSql1 "select bs.level_id, sw.story_id from story_work sw, biblestory bs, expositiontranslation t where t.id = " $vTranslationID " and t.work_id = sw.work_id and sw.story_id = bs.id order by bs.level_id limit 1";
  7304.             //echo $sSql1;
  7305.             $aRet $this->getRowData($sSql1);
  7306.         }
  7307.         return $aRet;        
  7308.     }
  7309.     
  7310.     function getVerseData($verse_id)
  7311.     {                
  7312.         $sSql "select t.language_id, l.bibliographiccode, c.book_id, b.translation_id, v.chapter_id from bibleverse v, biblechapter c, biblebook b, bibletranslation t, language l where v.id = " $verse_id " and v.chapter_id = c.id and c.book_id = b.id and b.translation_id = t.id and t.language_id = l.id";
  7313.     // echo $sSql."<br>";   
  7314.            $aRet $this->getRowData($sSql);  
  7315.         return $aRet;   
  7316.     }
  7317.     
  7318.     function getBibleTranslationListByLanguage($language_id=null)
  7319.     {            
  7320.         $sGroupOrder $this->getGroupOrderForBibleTranslation($language_id);
  7321.         
  7322.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name as name, t.url, bk.url as first_book_url, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as group_name, " $sGroupOrder " as group_order, true as has_book, true as has_chapter, l.bibliographiccode"
  7323.                 ." FROM language l, bibletranslation t"
  7324.                 ." join ("
  7325.                 ." select distinct on (t2.id) t2.id as translation_id, cb.url"
  7326.                 ." from bibletranslation t2, biblebook b, canonicalbiblebook cb where b.translation_id = t2.id and cb.id = b.canonicalization_id"                
  7327.                 ." order by t2.id, b.ordering"
  7328.                 .") as bk on t.id = bk.translation_id";
  7329.                 
  7330.       $sSql .= " WHERE t.enabled and t.language_id = l.id";
  7331.       $sSql .= " order by group_order, language_name, t.name";
  7332.  //    echo $sSql."<br>";   
  7333.            return $this->getNativeQueryResults($sSql);  
  7334.     }
  7335.     
  7336.     function getGroupOrderForBibleTranslation($language_id)
  7337.     {            
  7338.         $sGroupOrder "";
  7339.         if(empty($language_id))
  7340.         {          
  7341.               $sGroupOrder "(case when language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end)";
  7342.         }
  7343.         else
  7344.         {          
  7345.               $sGroupOrder "(case when language_id = " $language_id " then 1 else case when language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end)";
  7346.         }
  7347.         return $sGroupOrder;
  7348.     } 
  7349.     
  7350.     function getLanguageStrForMeta($vLanguageID)
  7351.     {
  7352.         $sRet "";
  7353.         if(!empty($vLanguageID))
  7354.         {
  7355.             $sSql1 "select '- ' || (case when nativename is not null and nativename <> '' and nativename <> name then nativename else name end) as name from language where id = " $vLanguageID;
  7356.             //echo $sSql1;
  7357.             $sRet $this->getSingleData($sSql1);
  7358.         }
  7359.         
  7360.         return $sRet;
  7361.     }
  7362.     
  7363.     function getCVerseInfo($vVerseIDs)
  7364.     {
  7365.         $aRet = array();
  7366.         if(!empty($vVerseIDs))
  7367.         {
  7368.             $sSql1 "select string_agg(distinct cv.id::text, ',') as cverse_ids, string_agg(distinct cc.id::text, ',') as cchapter_ids, string_agg(distinct cc.ordering::text, ',' order by cc.ordering::text) as cchapter_orders from canonicalbibleverse cv, canonicalbiblechapter cc, canonicalbiblebook cb, bibleverse v, (select * from canonicalbibleverse_bibleverse where bibleverse_id in (" $vVerseIDs ")) as cvv where v.id in (" $vVerseIDs ") and v.id = cvv.bibleverse_id and cv.id = cvv.canonicalbibleverse_id and cv.chapter_id = cc.id";
  7369.         //    echo $sSql1;
  7370.             $aRet $this->getRowData($sSql1);
  7371.             if(!empty($aRet))
  7372.             {
  7373.                 $sChapterOrders $aRet['cchapter_orders'];
  7374.                 $aChapterOrder explode(",",$sChapterOrders);
  7375.                 $nChapterOrder $aChapterOrder[0];
  7376.                 $aRet['first_chapter_index'] = $nChapterOrder;
  7377.             }
  7378.         }
  7379.         
  7380.         return $aRet;
  7381.     }
  7382.     
  7383.     function getBibleTranslationListForLanguage($language_id)
  7384.     {          
  7385.         $sSql "SELECT t.id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name, t.name as name, t.url, bk.url as first_book_url, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as group_name, 1 as group_order, true as has_book, true as has_chapter, l.bibliographiccode"
  7386.                 ." FROM language l, bibletranslation t"
  7387.                 ." join ("
  7388.                 ." select distinct on (t2.id) t2.id as translation_id, cb.url"
  7389.                 ." from bibletranslation t2, biblebook b, canonicalbiblebook cb where b.translation_id = t2.id and cb.id = b.canonicalization_id"                
  7390.                 ." order by t2.id, b.ordering"
  7391.                 .") as bk on t.id = bk.translation_id";
  7392.                 
  7393.       $sSql .= " WHERE l.id = " $language_id " and t.enabled and t.language_id = l.id";
  7394.       $sSql .= " order by group_order, language_name, t.name";
  7395.  //    echo $sSql."<br>";   
  7396.            return $this->getNativeQueryResults($sSql);  
  7397.     }
  7398.     
  7399.     function getYoutubeID($vMediaUrl)
  7400.     {
  7401.         $sRet null;
  7402.         $sStrToCheck "youtube.com/embed/";
  7403.         $nPos strpos($vMediaUrl$sStrToCheck);
  7404.         if($nPos !== false)
  7405.         {
  7406.             $nLen strlen($sStrToCheck);
  7407.             $sRet substr($vMediaUrl$nPos+$nLen);
  7408.             $nPosQ strpos($sRet"&");
  7409.             if($nPosQ !== false)
  7410.             {
  7411.                 $sRet substr($sRet0$nPosQ);
  7412.             }
  7413.         }
  7414.         
  7415.         return $sRet;
  7416.     }
  7417.     
  7418.     function getLanguageListForConceptHub()
  7419.     {            
  7420.         $sSql "select id, (case when nativename is not null and nativename <> '' then nativename else name end) as name from language where id in (select distinct t.language_id from concept_work cl, expositiontranslation t where cl.work_id = t.work_id)";                
  7421.         $sSql .= " order by name";
  7422. //    echo $sSql . "<br>";            
  7423.         return $this->getNativeQueryResults($sSql);
  7424.     }
  7425.     
  7426.     function getWorkTranslationData($translation_id)
  7427.     {                
  7428.         $sSql "SELECT language_id, work_id"
  7429.                 ." FROM expositiontranslation" 
  7430.                 ." WHERE id = " $translation_id;
  7431.   //   echo $sSql."<br>";   
  7432.            $aRet $this->getRowData($sSql);        
  7433.                 
  7434.         return $aRet;   
  7435.     }
  7436.     
  7437.     function getChapterExplanationsForPopup($translation_id)
  7438.     {   
  7439.         $aTrans $this->getWorkTranslationData($translation_id);
  7440.         $nLanguageID $aTrans['language_id'];
  7441.         $nWorkID $aTrans['work_id'];
  7442.         $sSql "SELECT t.id as translation_id, t.translatedtitle as explanationtitle, bs.chapter_id as cchapter_id, null as chapter_id, cbc.ordering as chapter_order, t.url as translation_url, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, case when t.language_id = " $nLanguageID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 end end as lang_order, case when t.id = " $translation_id " then 1 else case when t.islanguagedefault then 2 else 3 end end as trans_order, w.id as work_id, t.is_modern, bs.id as story_id, t.language_id, (case when l.nativename is not null and l.nativename <> '' then l.nativename else l.name end) as language_name"
  7443.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs, canonicalbiblechapter cbc, language l"
  7444.                 ." WHERE bs.chapter_id in (select cbc2.id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $nWorkID " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and t.language_id = l.id"
  7445.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic order by lang_order, language_name, t.is_modern desc, trans_order";
  7446.   //    echo $sSql . "<br>";          
  7447.         return $this->getNativeQueryResults($sSql); 
  7448.     }
  7449.     
  7450.     function getAuthorListForStoryHub()
  7451.     {        
  7452.         $nCategoryId $this->CATEGORY_ID_BIBLE_STORY;   
  7453.         $sSql "select id, name from vpersonforcombo where id in (select distinct bp.person_id from bibliographicdata_person bp, translation_bibliographicdata tb, expositiontranslation t where bp.bibliographicdata_id = tb.bibliographicdata_id and t.id = tb.translation_id and t.work_id IN (SELECT sw.work_id FROM story_work sw, biblestory st where st.level_id = " $this->STORY_LEVEL_ID_BIBLE " and sw.story_id = st.id))";                
  7454.         $sSql .= " order by name";
  7455. //    echo $sSql . "<br>";            
  7456.         return $this->getNativeQueryResults($sSql);
  7457.     }
  7458.     
  7459.     function getSWWorkTranslations($work_ids$language_id$work_type)
  7460.     {   
  7461.         $sSql "SELECT t.id as translation_id, t.name, t.translatedtitle, (case when b.datecreated is null then '' else ' (' || b.datecreated || ')' end) as datestr, t.url, l.righttoleft, w.title as work_title, t.isoriginal, w.id as work_id, t.language_id"
  7462.                 ." FROM language l, expositionwork w, expositiontranslation t left join (select tb.translation_id, b.datecreated from bibliographicdata b, translation_bibliographicdata tb where b.id = tb.bibliographicdata_id) as b on t.id = b.translation_id"
  7463.                 ." WHERE w.swedenborgtype is not null and w.ispublic";
  7464.                 
  7465.        if(!empty($work_ids))
  7466.               $sSql .= " and w.id in (" $work_ids ")"
  7467.                            
  7468.        if(!empty($language_id))
  7469.               $sSql .= " and t.language_id = " $language_id;  
  7470.               
  7471.        if(!empty($work_type))
  7472.               $sSql .= " and w.swedenborgtype = '" $work_type "'"
  7473.                     
  7474.        $sSql .= " and t.ispublic and t.work_id = w.id and t.language_id = l.id" 
  7475.             ." AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;              
  7476.                 
  7477.        $sSql .= " order by work_id, t.name";
  7478.   //   echo $sSql."<br>";   
  7479.           
  7480.          $aRet $this->getNativeQueryResults($sSql);
  7481.            $nLen count($aRet);
  7482.            for($i=0;$i<$nLen;$i++)
  7483.            {
  7484.                $sTransName $aRet[$i]['name'];
  7485.                $sTranslatedTitle $aRet[$i]['translatedtitle'];
  7486.                $sWorkTitle $aRet[$i]['work_title'];
  7487.                $sDateStr $aRet[$i]['datestr'];
  7488.                $bOriginal $aRet[$i]['isoriginal'];
  7489.                $nLanguageID $aRet[$i]['language_id'];
  7490.                $sIdentifier $this->convertWorkTransIdentifier($sTransName$sTranslatedTitle$sWorkTitle$sDateStr$bOriginal$nLanguageID);
  7491.                $aRet[$i]["identifier"] = $sIdentifier;
  7492.            }
  7493.            return $aRet;  
  7494.     }
  7495.     
  7496. /*    function showEnglishTrans($vLanguageID)
  7497.     {
  7498.         return ($vLanguageID == $this->LANGUAGE_ID_ZULU);
  7499.     }*/
  7500.     
  7501.     function fixVerseText($vStr)
  7502.     {
  7503.         $sRet preg_replace("/~ppss~[^~]+~ppee~/"""$vStr);
  7504.           $sRet preg_replace("/\<sup\>[^\<]+\<\/sup\>/"""$sRet);
  7505.           $sRet str_replace('"'"'"$sRet);
  7506.           $sRet str_replace(array("\r""\n"), " "$sRet);
  7507.           $sRet strip_tags($sRet);
  7508.           return $sRet;
  7509.     }
  7510.     
  7511.     function getWorkPassageContents($passage_id,$translation_id)
  7512.     {      
  7513.         $sSql "select array_to_string(array_agg(d.text ORDER BY tu.ordering, d.ordering),'') as content from expositiontranslationtext tt, expositiontextunit tu, expositiondisplayitem d where tu.passage_id = " $passage_id " and tt.translation_id = " $translation_id;
  7514.         $sSql .= " and tu.id = tt.placement_id and d.container_id = tt.id";
  7515.   //   echo $sSql."<br>";  
  7516.           $sRet $this->getSingleData($sSql);  
  7517.         return $sRet
  7518.     }
  7519.     
  7520.     function fixWorkText($vStr)
  7521.     {        
  7522.           $sRet strip_tags($vStr);
  7523.           $sRet str_replace(array("\r""\n"), " "$sRet);
  7524.           $sRet str_replace("---"""$sRet);  
  7525.           $sRet str_replace('"'"'"$sRet);        
  7526.           $sRet preg_replace('!\s+!'' '$sRet);
  7527.           return $sRet;
  7528.     }
  7529.     
  7530.     function getWorkTranslationDesc($translation_id)
  7531.     {                
  7532.         $sSql "SELECT description"
  7533.                 ." FROM expositiontranslation" 
  7534.                 ." WHERE id = " $translation_id;
  7535.   //   echo $sSql."<br>";   
  7536.            $sRet $this->getSingleData($sSql);  
  7537.         return $sRet;   
  7538.     }
  7539.     
  7540.     function getExplanationContents($translation_id)
  7541.     {      
  7542.         $sSql "select array_to_string(array_agg(d.text ORDER BY tu.ordering, d.ordering),'') as content from expositiontranslationtext tt, expositiontextunit tu, expositiondisplayitem d where tt.translation_id = " $translation_id;
  7543.         $sSql .= " and tu.id = tt.placement_id and d.container_id = tt.id";
  7544.   //   echo $sSql."<br>";  
  7545.           $sRet $this->getSingleData($sSql);  
  7546.         return $sRet
  7547.     }
  7548.     
  7549.     function isExplainedVerse($translation_id$verse_id)
  7550.     {      
  7551.         $sSql "select v.id as verse_id FROM (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_VERSE ") as bs, canonicalbibleverse cv, bibleverse v, canonicalbibleverse_bibleverse cvv,"
  7552.                     ." expositionwork w, expositiontranslation t, story_work sw"                     
  7553.                     ." WHERE t.id = " $translation_id " and v.id = " $verse_id
  7554.                     ." and t.work_id=w.id and w.id = sw.work_id and sw.story_id = bs.id"     
  7555.                     ." and bs.startverse_id = cv.id"   
  7556.                     ." and cv.id = cvv.canonicalbibleverse_id and v.id = cvv.bibleverse_id"
  7557.                     ." and w.ispublic and t.ispublic";
  7558.   //   echo $sSql."<br>";  
  7559.           $nID $this->getSingleData($sSql);  
  7560.         return ($nID != ''); 
  7561.     }
  7562.     
  7563.     function replacePopupStr($str)
  7564.     {
  7565.         $sRet $str;
  7566.         $sPopupStartMark "~ppss~";
  7567.         $sPopupEndMark "~ppee~";
  7568.         $sRet str_replace($sPopupStartMark'<a data-toggle="popover" style="cursor: pointer;" data-content="'$sRet);    
  7569.         $sRet str_replace($sPopupEndMark'"></a>'$sRet);
  7570.         return $sRet;
  7571.     }
  7572.     
  7573.     function getDailyVerse($request)
  7574.     {      
  7575.         $sRet "";        
  7576.         $sSql "SELECT text FROM page_message WHERE id = " $this->PAGE_MESSAGE_ID_EMAIL_BY_DATE;
  7577.             
  7578.         //echo $sSql."<br>";
  7579.         $sText $this->getSingleData($sSql);    
  7580.         if(!empty($sText))
  7581.         {
  7582.             $locale $request->getLocale();
  7583.             $nLanguageID =  $this->getLanguageIDByShortCode($locale);
  7584.             $sSql "SELECT startverse_id, endverse_id, commentary, work_id, passage_id, subsection_num FROM emailbydate WHERE date_to_send = CURRENT_DATE limit 1";            
  7585.             //echo $sSql."<br>";
  7586.             $aData $this->getRowData($sSql);        
  7587.             if(!empty($aData))
  7588.             {        
  7589.                 $startverse_id trim($aData['startverse_id']); 
  7590.                 $endverse_id trim($aData['endverse_id']); 
  7591.                 $commentary trim($aData['commentary']); 
  7592.                 $work_id trim($aData['work_id']); 
  7593.                 $passage_id trim($aData['passage_id']); 
  7594.                 $subsection_num trim($aData['subsection_num']); 
  7595.                 
  7596.                 $bMultipleVerses = (!empty($endverse_id) && $endverse_id != $startverse_id);
  7597.                 $sVerses "";
  7598.                 $sBibleTransIDs "";    
  7599.             //    $aBibleTransIDUnique = array();
  7600.                 $aVerse = array();
  7601.                 $aCVerseID = array();
  7602.         
  7603.                 $sLinkStart "";
  7604.                 $sVerseLinkText "";
  7605.             
  7606.                 // Get first verse info    
  7607.                 $sVerseUrl $sLinkStart;
  7608.                 $sVerseUrlEnd "";
  7609.                 $sWorkLink "";
  7610.                                                 
  7611.                 // Link to full chapter page
  7612.                 $sSql1 "SELECT bc.id as chapter_id, cbv.ordering as verse_order, t.url || '/' || cb.url || '/' || cc.ordering as link, cc.ordering || ':' || cbv.ordering as linktext,";
  7613.                 $sSql1 .= " bv.content";                 
  7614.                 $sSql1 .= " as text, cb.id as cbook_id, cc.id as cchapter_id, cc.ordering as cchapter_order, bc.book_id, cbv.id as cverse_id, cb.url || '/' || cc.ordering as link_end FROM bibleverse bv, biblechapter bc, biblebook b, bibletranslation t, canonicalbibleverse_bibleverse cbv_bv, canonicalbibleverse cbv, canonicalbiblechapter cc, canonicalbiblebook cb where t.language_id = " $nLanguageID " and cbv.id = " $startverse_id " and cbv.id = cbv_bv.canonicalbibleverse_id and bv.id = cbv_bv.bibleverse_id and bv.chapter_id = bc.id and bc.book_id = b.id and b.translation_id = t.id and cbv.chapter_id = cc.id and cc.book_id = cb.id order by t.languagedefault desc limit 1"
  7615.             //    echo $sSql1 . "<br>";
  7616.                 $aFirstVerse $this->getRowData($sSql1);
  7617.                 if(!empty($aFirstVerse))
  7618.                 {
  7619.                     $nFirstChapterID $aFirstVerse['chapter_id'];
  7620.                     $nFirstVerseOrder $aFirstVerse['verse_order'];            
  7621.                     $sVerseUrl .= 'bible/'.$aFirstVerse['link'];
  7622.                     $sVerseLinkText $aFirstVerse['linktext'];
  7623.                     $sVerses .= $this->replacePopupStr($aFirstVerse['text']);
  7624.                     $nFirstCBookID $aFirstVerse['cbook_id'];
  7625.                     $nFirstCChapterID $aFirstVerse['cchapter_id'];
  7626.                     $nFirstCChapterOrder $aFirstVerse['cchapter_order'];
  7627.                     $nFirstBookID $aFirstVerse['book_id'];
  7628.                     $nFirstCVerseID $aFirstVerse['cverse_id'];
  7629.                     $sVerseUrlEnd $aFirstVerse['link_end'];
  7630.                     $aCVerseID[] = $nFirstCVerseID;
  7631.                                                             
  7632.                     // Get book name
  7633.                     $sSql2 "select name from canonicalbiblebooklanguage where book_id = " $nFirstCBookID " and language_id = " $nLanguageID " and not is_abbr order by is_standard desc limit 1";
  7634.                     $sBookName $this->getSingleData($sSql2);
  7635.                     $sVerseLinkText $sBookName " " $sVerseLinkText;
  7636.                     
  7637.                     if($bMultipleVerses)
  7638.                     {
  7639.                         //$sSql2 = "select ordering from canonicalbibleverse where id = " . $endverse_id;
  7640.                         $sSql2 "SELECT cc.book_id as cbook_id, cc.id as cchapter_id, cbv.ordering as verse_order, bc.id as chapter_id, bc.book_id, cc.ordering as cchapter_order FROM bibleverse bv, biblechapter bc, biblebook b, bibletranslation t, canonicalbibleverse_bibleverse cbv_bv, canonicalbibleverse cbv, canonicalbiblechapter cc, canonicalbiblebook cb where t.language_id = " $nLanguageID " and cbv.id = " $endverse_id " and cbv.id = cbv_bv.canonicalbibleverse_id and bv.id = cbv_bv.bibleverse_id and bv.chapter_id = bc.id and bc.book_id = b.id and b.translation_id = t.id and cbv.chapter_id = cc.id and cc.book_id = cb.id order by t.languagedefault desc limit 1";
  7641.                         $aSecondVerse $this->getRowData($sSql2);
  7642.                         $nLastCBookID $aSecondVerse['cbook_id'];
  7643.                         $nLastCChapterID $aSecondVerse['cchapter_id'];
  7644.                         $nLastVerseOrder $aSecondVerse['verse_order'];
  7645.                         $nLastChapterID $aSecondVerse['chapter_id'];
  7646.                         $nLastBookID $aSecondVerse['book_id'];
  7647.                         $nLastCChapterOrder $aSecondVerse['cchapter_order'];
  7648.                     
  7649.                         $sSql3 "";
  7650.                         $bSameChapter false;
  7651.                         $bSameBook false;
  7652.                         if($nFirstCChapterID == $nLastCChapterID)
  7653.                         {
  7654.                             $bSameChapter true;
  7655.                             $bSameBook true;
  7656.                             $sSql3 "SELECT bv.content as text, cbv.id FROM bibleverse bv, canonicalbibleverse_bibleverse cbv_bv, canonicalbibleverse cbv where bv.chapter_id = " $nFirstChapterID " and bv.id = cbv_bv.bibleverse_id and cbv.id = cbv_bv.canonicalbibleverse_id and cbv.ordering > " $nFirstVerseOrder " and cbv.ordering <= " $nLastVerseOrder " order by cbv.ordering"
  7657.                         }
  7658.                         else if($nFirstCBookID == $nLastCBookID)
  7659.                         {
  7660.                             $bSameBook true;
  7661.                             $sSql3 "SELECT bv.content as text, cbv.id FROM bibleverse bv, canonicalbibleverse_bibleverse cbv_bv, canonicalbibleverse cbv, canonicalbiblechapter cc, biblechapter bc where bc.book_id = " $nFirstBookID " and bv.chapter_id = bc.id and bv.id = cbv_bv.bibleverse_id and cbv.id = cbv_bv.canonicalbibleverse_id and cbv.chapter_id = cc.id and ((bv.chapter_id = " $nFirstChapterID " and cbv.ordering > " $nFirstVerseOrder ") or (cc.ordering > " $nFirstCChapterOrder " and cc.ordering < " $nLastCChapterOrder ") or (bv.chapter_id = " $nLastChapterID " and cbv.ordering <= " $nLastVerseOrder ")) order by cc.ordering, cbv.ordering"
  7662.                         }
  7663.                         else
  7664.                         {
  7665.                             $sSql3 "select * from (SELECT bv.content as text, cbv.id, cb.ordering as book_order, cc.ordering as chapter_order, cbv.ordering as verse_order FROM bibleverse bv, canonicalbibleverse_bibleverse cbv_bv, canonicalbibleverse cbv, canonicalbiblechapter cc,  canonicalbiblebook cb, biblechapter bc where bc.book_id = " $nFirstBookID " and bv.chapter_id = bc.id and bv.id = cbv_bv.bibleverse_id and cbv.id = cbv_bv.canonicalbibleverse_id and cbv.chapter_id = cc.id and cc.book_id = cb.id and ((bv.chapter_id = " $nFirstChapterID " and cbv.ordering > " $nFirstVerseOrder ") or (cc.ordering > " $nFirstCChapterOrder ")) "
  7666.                             $sSql3 .= " union SELECT bv.content as text, cbv.id, cb.ordering as book_order, cc.ordering as chapter_order, cbv.ordering as verse_order FROM bibleverse bv, canonicalbibleverse_bibleverse cbv_bv, canonicalbibleverse cbv, canonicalbiblechapter cc,  canonicalbiblebook cb, biblechapter bc where bc.book_id = " $nLastBookID " and bv.chapter_id = bc.id and bv.id = cbv_bv.bibleverse_id and cbv.id = cbv_bv.canonicalbibleverse_id and cbv.chapter_id = cc.id and cc.book_id = cb.id and ((bv.chapter_id = " $nLastChapterID " and cbv.ordering <= " $nLastVerseOrder ") or (cc.ordering < " $nLastCChapterOrder ")) ) as t order by book_order, chapter_order, verse_order";
  7667.                         }
  7668.                 //        echo $sSql3 . "<br>";
  7669.                         $aOtherVerse $this->getListData($sSql3);
  7670.                         if(!empty($aOtherVerse))
  7671.                         {
  7672.                         //    $sVerseLink .= "-".$nLastVerseOrder;
  7673.                         //    $sVerseUrl .= "-".$nLastVerseOrder;
  7674.                         
  7675.                             if($bSameChapter)
  7676.                                 $sVerseLinkText .= "-".$nLastVerseOrder;
  7677.                             else if($bSameBook)
  7678.                             {
  7679.                                 $sVerseLinkText .= "-".$nLastCChapterOrder.":".$nLastVerseOrder;
  7680.                             }    
  7681.                             else
  7682.                             {
  7683.                                 // Get last book name
  7684.                                 $sSql2 "select name from canonicalbiblebooklanguage where book_id = " $nLastCBookID " and language_id = " $nLanguageID " and not is_abbr order by is_standard desc limit 1";
  7685.                                 $sLastBookName $this->getSingleData($sSql2);
  7686.                                 $sVerseLinkText .= " - " $sLastBookName " " $nLastCChapterOrder.":".$nLastVerseOrder;
  7687.                             }    
  7688.                                     
  7689.                             //echo $sVerseLinkText;
  7690.                             
  7691.                             foreach($aOtherVerse as $v)
  7692.                             {                                
  7693.                                 $sVerses .= " "$this->replacePopupStr($v['text']);
  7694.                                 $aCVerseID[] = $v['id'];
  7695.                             }
  7696.                         }
  7697.                     }
  7698.                 }    
  7699.                 
  7700.     //            $sVerseLink = "<a href='" . $sVerseLink . "'>" . $sVerseLinkText . "</a>";    
  7701.             //    $sVerses = $sVerseLinkText . "<br><br>" . $sVerses;
  7702.             
  7703.                 $aCVerseContent = array();
  7704.                 $sCVerseIDs implode(","$aCVerseID);
  7705.                 if(!empty($sBibleTransIDs) && !empty($sCVerseIDs))
  7706.                 {                    
  7707.                     $sSql2 "SELECT b.translation_id, array_to_string(array_agg(bv.content ORDER BY cb.ordering, cc.ordering, cbv.ordering), ' ') as text FROM bibleverse bv, biblechapter bc, biblebook b, canonicalbibleverse_bibleverse cbv_bv, canonicalbibleverse cbv, canonicalbiblechapter cc,  canonicalbiblebook cb where b.translation_id in (" $sBibleTransIDs ") and cbv.id in (" $sCVerseIDs ") and cbv.id = cbv_bv.canonicalbibleverse_id and bv.id = cbv_bv.bibleverse_id and bv.chapter_id = bc.id and bc.book_id = b.id and cbv.chapter_id = cc.id and cc.book_id = cb.id group by b.translation_id";    
  7708.             //    echo $sSql2 . "<br>";                
  7709.                     $aTemp $this->getListData($sSql2);
  7710.                     foreach($aTemp as $t)
  7711.                     {
  7712.                         $aCVerseContent[$t['translation_id']] = $this->replacePopupStr($t['text']);
  7713.                     }
  7714.                 }
  7715.                 
  7716.                 if(!empty($passage_id))
  7717.                 {
  7718.                     // Get work link
  7719.                     $sSql2 "SELECT distinct on (w.id) w.id, p.swedenborgsection, 'exposition/translation/' || t.url || '/' || d.url || '/' || p.ordering as link"
  7720.                     ." FROM expositionwork w, expositiontranslation t, expositionpassage p, expositiondivision d"
  7721.                     ." WHERE p.id = " $passage_id " and p.division_id = d.id and d.work_id = w.id and t.work_id=w.id and t.language_id = ".$nLanguageID" and t.ispublic and w.ispublic";
  7722.                       $sSql2 .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  7723.                       $sSql2 .= " order by w.id, t.islanguagedefault desc";
  7724.                       $aWork $this->getRowData($sSql2);
  7725.                       if(!empty($aWork))
  7726.                       {
  7727.                           $nWorkID $aWork['id'];
  7728.                           $sSql2 "SELECT name from expositionworklanguage where language_id = " $nLanguageID " and work_id = " $nWorkID " order by is_standard desc";
  7729.                       //    echo $sSql2;
  7730.                         $sWorkName $this->getSingleData($sSql2);
  7731.                           
  7732.                           $sRef $sWorkName.' '.$aWork['swedenborgsection'];
  7733.                           if($subsection_num 1)
  7734.                               $sRef .= "[".$subsection_num."]";
  7735.                           
  7736.                           $sLinkStr $aWork['link'];
  7737.                           $sWorkLink "<a href='".$sLinkStart.$sLinkStr."'>".$sRef."</a>";
  7738.                       }
  7739.                           
  7740.                   }
  7741.                   
  7742.                   $sText str_replace('[VERSE_RANGE_TITLE]'$sVerseLinkText$sText);  
  7743.                 $sText str_replace('[VERSE_RANGE_TEXT]'$sVerses$sText);
  7744.                 $sText str_replace('[BIBLE_SOURCE_URL]'$sVerseUrl$sText);            
  7745.                 $sText str_replace('[WORK_LINK]'$sWorkLink$sText);
  7746.                 $sText str_replace('[COMMENTARY]'$commentary$sText);
  7747.                 
  7748.                 $sRet $sText;
  7749.             }  
  7750.         }
  7751.           
  7752.           return $sRet;         
  7753.     }
  7754.     
  7755.     function getCategoryList($language_id$category_id$locale)
  7756.     {
  7757.         $nUILanguageID $this->getLanguageIDByShortCode($locale);
  7758.         $sSql "SELECT t.translatedtitle AS title, t.url as translation_url, d.url as division_url, '" $this->MULTI_URL_INDICATOR_EXPLANATION "_' || t.url as ref_column_spec, w.id as work_id, t.id as translation_id"
  7759.                 ." FROM expositionwork w, expositiontranslation t, (select distinct on (work_id) work_id, url, min(ordering) as ordering from expositiondivision group by work_id, url) as d"
  7760.                 ." WHERE t.work_id=w.id and w.id in (select work_id from work_category where category_id = " $category_id ")"
  7761.                     ." and d.work_id = w.id AND w.ispublic AND t.ispublic"
  7762.                     ." AND w.swedenborgtype IS NULL"
  7763.                     ." AND t.translatedtitle IS NOT NULL and t.id in (";
  7764.           
  7765.           $sSql .= "SELECT distinct on (w.id) t.id"
  7766.                 ." FROM expositionwork w, expositiontranslation t WHERE ";
  7767.                 
  7768.           $sSql .= " t.work_id=w.id order by w.id, (case when t.language_id = " $nUILanguageID " then 1 else case when t.language_id = " $language_id " then 2 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 3 else 4 end end end), t.islanguagedefault desc)"
  7769.                     ." AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT;
  7770.                              
  7771.           $sSql .= " order by w.ordering, t.translatedtitle";
  7772.  //   echo $sSql."<br>";
  7773.         return $this->getNativeQueryResults($sSql);
  7774.     }
  7775.     
  7776.     function getReadingPlanStepBasicInfo($readingPlanUrl$stepOrder$request)
  7777.     {            
  7778.         $locale $request->getLocale();    
  7779.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  7780.             
  7781.         $sSql "SELECT rs.id, rs.name, rs.text, rs.closing_text, rs.image_file, rs.image_title, rs.video_link, rs.youtube_id, rs.video_notice, ";
  7782.         $sSql .= "case when rl.name is null then r.name else rl.name end";        
  7783.         $sSql .= " as plan_title, rs.ordering as step_order, rs.type_id, rs.work_id, rs.passage_id, rs.explanation_id";
  7784.         $sSql .= " FROM ";
  7785.         $sSql .= " (select rsa.id, case when rsl.name is null then rsa.name else rsl.name end as name, rsa.readingplan_id, rsa.startverse_id, rsa.endverse_id, rsa.ordering, rsa.type_id, rsa.work_id, rsa.passage_id, rsa.explanation_id, case when rsl.text is null then rsa.text else rsl.text end as text, case when rsl.closing_text is null then rsa.closing_text else rsl.closing_text end as closing_text, i.file as image_file, i.title as image_title, e.location as video_link, e.youtube_id, e.notice as video_notice from readingplanstep rsa left join (select * from readingplanstep_language where language_id = " .$nLanguageID ") rsl on rsa.id = rsl.readingplanstep_id left join image i on rsa.image_id = i.id left join (select * from embed where visibilitydefault) e on rsa.embed_id = e.id) rs, ";
  7786.             $sSql .= " readingplan r left join (select * from readingplan_language where language_id = " .$nLanguageID ") rl on r.id = rl.readingplan_id ";  
  7787.         $sSql .= " where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  7788.                 ." and r.id = rs.readingplan_id"
  7789.                  ." and rs.ordering = " $stepOrder;
  7790. //   echo $sSql . "<br>";             
  7791.         $aRet $this->getRowData($sSql);
  7792.         return $aRet;
  7793.     }
  7794.     
  7795.     function getDefaultWorkTranslation($work_id$request)
  7796.     {   
  7797.         $locale $request->getLocale();             
  7798.         $sLangStr "(case when t.language_id in (select id from language where shortcode = '" trim(str_replace("'""''"$locale)) . "') then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 else 3 end end)";
  7799.             
  7800.         $sSql "SELECT t.id, t.url"
  7801.                 ." FROM language l, expositionwork w, expositiontranslation t"
  7802.                 ." WHERE w.id = " $work_id " and w.ispublic and t.work_id = w.id"
  7803.                 ." and t.ispublic and t.language_id = l.id"               
  7804.                 ." AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT
  7805.                 
  7806.        $sSql .= " order by " $sLangStr ", t.islanguagedefault desc limit 1";
  7807.   //   echo $sSql."<br>";   
  7808.           
  7809.          $aRet $this->getRowData($sSql);           
  7810.            return $aRet;  
  7811.     }
  7812.     
  7813.     function getChapterExplanationWorksForPopup($translation_id)
  7814.     {   
  7815.         $aTrans $this->getWorkTranslationData($translation_id);
  7816.         $nLanguageID $aTrans['language_id'];
  7817.         $nWorkID $aTrans['work_id'];
  7818.         $sSql "SELECT * from (select distinct on (work_id) t.id as translation_id,  t.translatedtitle as explanationtitle, bs.chapter_id as cchapter_id, null as chapter_id, cbc.ordering as chapter_order, t.url as translation_url, '" $this->MULTI_URL_INDICATOR_EXPLANATION "' || '_' || t.url as explanation_spec, case when t.language_id = " $nLanguageID " then 1 else case when t.language_id = " $this->LANGUAGE_ID_ENGLISH " then 2 end end as lang_order, case when t.id = " $translation_id " then 1 else case when t.islanguagedefault then 2 else 3 end end as trans_order, w.id as work_id, t.is_modern, bs.id as story_id"
  7819.                 ." FROM expositionwork w, expositiontranslation t, story_work sw, biblestory bs, canonicalbiblechapter cbc, language l"
  7820.                 ." WHERE bs.chapter_id in (select cbc2.id from biblestory bs2, story_work sw2, canonicalbiblechapter cbc2 where sw2.work_id = " $nWorkID " and sw2.story_id = bs2.id and cbc2.id = bs2.chapter_id) and sw.story_id = bs.id and w.id = sw.work_id and t.work_id=w.id and t.language_id = l.id"
  7821.                 ." and cbc.id = bs.chapter_id and w.ispublic AND t.ispublic order by w.id, lang_order, t.is_modern desc, trans_order) as t order by lang_order, is_modern desc, trans_order";
  7822.      // echo $sSql . "<br>";          
  7823.         return $this->getNativeQueryResults($sSql); 
  7824.     }
  7825.     
  7826.     function getWorkPassages($work_id)
  7827.     {
  7828.         $sSql "SELECT p.swedenborgsection as passage_num"
  7829.                 ." FROM expositionpassage p, expositiondivision d"
  7830.                 ." WHERE d.work_id = " $work_id " and p.division_id = d.id"
  7831.                 ." order by p.ordering";
  7832.      //          echo $sSql."<br>";        
  7833.         $aRet $this->getNativeQueryResults($sSql);                
  7834.         return $aRet;          
  7835.     } 
  7836.     
  7837.     // Get refs for "Kempton view"
  7838.     function getBibleCrossRef($aVerseInfo$bChapter$bCheck=false)
  7839.     {            
  7840.         if(empty($aVerseInfo))
  7841.             return array();
  7842.                 
  7843.         $verseLanguage null;        
  7844.         $sCVerseIDs $aVerseInfo['CVerseIDs'];
  7845.         $verseLanguage $aVerseInfo['LanguageID'];
  7846.         
  7847.         if($verseLanguage == '')
  7848.             $verseLanguage $this->LANGUAGE_ID_ENGLISH;
  7849.                 
  7850.         $sCChapterIDs $aVerseInfo['CChapterIDs'];   
  7851.     
  7852.         if($sCVerseIDs == '' && $sCChapterIDs == '') {
  7853.             return array();
  7854.         } else {
  7855.             return $this->getBibleCrossRefInfo($bChapter$verseLanguage$sCVerseIDs$sCChapterIDs$bCheck);
  7856.         }
  7857.     }
  7858.     
  7859.     function getBibleCrossRefInfo($bChapter$language_id$sCVerseIDs$sChapterIDs$bCheck)
  7860.     {            
  7861.         if($sCVerseIDs == '' && $sChapterIDs == ''
  7862.             return array();
  7863.             
  7864.         $nDefaultLanguageID $this->LANGUAGE_ID_ENGLISH// English    
  7865.                     
  7866.         $sTable " (";
  7867.         if ($sCVerseIDs <> '')
  7868.         {                
  7869.             $aCVerseID explode(","$sCVerseIDs);
  7870.             $nFirstCVerseID current($aCVerseID);
  7871.             $nLastCVerseID end($aCVerseID);
  7872.             $bSingleVerse = ($nFirstCVerseID == $nLastCVerseID);
  7873.             if($bSingleVerse)
  7874.             {            
  7875.                    $sTable .= "select rb.id, rc.originallinktext as bible_ref FROM refbible rb, refcombined rc, canonicalbibleverse cv1, canonicalbiblechapter cc1, canonicalbibleverse cv2, canonicalbiblechapter cc2, canonicalbibleverse cva where cc1.id in (" $sChapterIDs ") and cc2 = cc1 and cv1.chapter_id = cc1.id and cv1.id = rb.startverse_id and rc.id = rb.container_id and cv2.chapter_id = cc2.id and cv2.id = rb.endverse_id and cva.id = " $nFirstCVerseID " and cv1.ordering = cva.ordering and cv2.ordering = cv1.ordering";
  7876.            }
  7877.            else
  7878.            {            
  7879.                    $sTable .= "select rb.id, rc.originallinktext as bible_ref, cc1.ordering as chapter_order, cv1.ordering as verse_order1, cv2.ordering as verse_order2 FROM refbible rb, refcombined rc, canonicalbibleverse cv1, canonicalbiblechapter cc1, canonicalbibleverse cv2, canonicalbiblechapter cc2, canonicalbibleverse cva, canonicalbibleverse cvb where cc1.id in (" $sChapterIDs ") and cc2 = cc1 and cv1.chapter_id = cc1.id and cv1.id = rb.startverse_id and cv2.chapter_id = cc2.id and cv2.id = rb.endverse_id and rc.id = rb.container_id and cva.id = " $nFirstCVerseID " and cvb.id = " $nLastCVerseID " and cv1.ordering >= cva.ordering and cv2.ordering <= cvb.ordering";
  7880.            }
  7881.         }        
  7882.         $sTable .= ") as br";    
  7883.         
  7884.         $sSql "select * from (SELECT distinct on (p.id, rc.originallinktext, br.bible_ref) p.id, rc.originallinktext as work_ref, br.bible_ref";
  7885.         if(!$bSingleVerse)
  7886.             $sSql .= ", br.chapter_order, br.verse_order1, br.verse_order2";
  7887.         
  7888.         $sSql .= ", t.translatedtitle AS title, p.swedenborgsection as num, t.url as translation_url, d.url as division_url, w.ordering as work_order, p.ordering, case when t.language_id = " $language_id " then 1 else 2 end as lang_order"
  7889.                 ." FROM expositionwork w, expositiontranslation t, expositiontextunit tu, expositionpassage p, expositiondivision d, ref_code r_c, refcombined rc, refexposition re, " $sTable
  7890.                 ." WHERE r_c.refbible_id = br.id and r_c.refexposition_id = re.id and rc.id = re.container_id and t.work_id=w.id and d.work_id = w.id and p.division_id = d.id and tu.id = re.startlocation_id and tu.passage_id = p.id";
  7891.           if($language_id == $nDefaultLanguageID)
  7892.           {
  7893.               $sSql .= " and t.language_id = " $language_id;
  7894.           }
  7895.           else
  7896.           {
  7897.               $sSql .= " and t.language_id in ( ".$language_id"," $nDefaultLanguageID ")";              
  7898.          }
  7899.           
  7900.           $sSql .= " and t.ispublic and w.ispublic and t.url is not null and t.url <> ''";
  7901.           $sSql .= " AND t.type_id = " $this->TRANSLATION_TYPE_ID_TEXT " order by p.id, rc.originallinktext, br.bible_ref, lang_order, t.islanguagedefault desc"
  7902.           
  7903.           if($bCheck)
  7904.               $sSql .= " limit 1";
  7905.           
  7906.           if($bSingleVerse)              
  7907.               $sSql .= ") as t2 order by title, ordering";
  7908.           else
  7909.               $sSql .= ") as t2 order by chapter_order, case when bible_ref like '%:%' then 2 else 1 end, verse_order1, verse_order2, bible_ref, title, ordering";
  7910.               
  7911. //     echo $sSql."<br>";
  7912.          
  7913.          $aRet $this->getNativeQueryResults($sSql);
  7914.          $nLen count($aRet);
  7915.            for($i=0;$i<$nLen;$i++)
  7916.            {
  7917.                $sWorkRef $aRet[$i]["work_ref"];
  7918.                $sNumPart $this->getRefNumPart($sWorkRef);
  7919.                $sSubSection "";
  7920.                if(is_numeric($sNumPart))
  7921.                 $aRet[$i]['passage_str'] = $aRet[$i]['num'];
  7922.             else
  7923.             {    
  7924.                    $sPattern '/\[(\d+)\]/';
  7925.                 $nCount preg_match_all($sPattern$sNumPart$matches);
  7926.                 if ($nCount 0)
  7927.                 {
  7928.                     $sSubSection trim(current(end($matches)));
  7929.                     $sNumPart str_replace(" [""["$sNumPart);
  7930.                 }                    
  7931.                 $aRet[$i]['passage_str'] = $sNumPart;
  7932.             }
  7933.             $aRet[$i]['subsection'] = $sSubSection;    
  7934.            }
  7935.            return $aRet;  
  7936.     }
  7937.     
  7938.     function getRefNumPart($vRef)
  7939.     {
  7940.         $sRet '';
  7941.     
  7942.         // first check patterns like 'Marriage (Index) 1 30' (the book name has a number at the end)
  7943.         $sPattern '/[^\d]\s[\d]+\s(\d[\d\s\[\]\-:]*)/';
  7944.         $nCount preg_match_all($sPattern$vRef$matches);
  7945.         if ($nCount 0)
  7946.             $sRet trim(current(end($matches)));
  7947.         else
  7948.         {        
  7949.             // if no match, check patterns like 'Ezekiel 47:1-23' (the book name has no number at the end)
  7950.             $sPattern '/[^\d]\s(\d[\d\s\[\]\-:]*)/';
  7951.             $nCount =  preg_match_all($sPattern$vRef$matches);        
  7952.             if ($nCount 0)
  7953.                 $sRet trim(current(end($matches)));            
  7954.         }
  7955.         return $sRet;    
  7956.     }
  7957.     
  7958.     function canUseSpeechToText()
  7959.     {        
  7960.         $user_agent = @$_SERVER['HTTP_USER_AGENT'];
  7961.         $sPattern '/(Chrome\/|Edg\/)/';
  7962.         $nCount preg_match_all($sPattern$user_agent$matches);
  7963.         $bRet = ($nCount 0);            
  7964.         return $bRet;
  7965.     }
  7966.     
  7967.     function getLanguageForSpeech($locale)
  7968.     {        
  7969.         // not support tl and la now.
  7970.         $sRet "en-US";
  7971.             if($locale == 'fr')
  7972.         $sRet "fr-FR";
  7973.         elseif($locale == 'zh')
  7974.             $sRet "zh";
  7975.         elseif($locale == 'de')
  7976.             $sRet "de-DE";
  7977.         elseif($locale == 'es')
  7978.             $sRet "es-ES";
  7979.         elseif($locale == 'it')
  7980.             $sRet "it-IT";
  7981.         elseif($locale == 'bg')
  7982.             $sRet "bg-BG";    
  7983.             elseif($locale == 'cs')
  7984.             $sRet "cs-CZ";
  7985.         elseif($locale == 'nl')
  7986.             $sRet "nl-NL";
  7987.         elseif($locale == 'ka')
  7988.             $sRet "ka-GE";
  7989.         elseif($locale == 'hi')
  7990.             $sRet "hi-IN";
  7991.         elseif($locale == 'ko')
  7992.             $sRet "ko-KR";
  7993.         elseif($locale == 'pt')
  7994.             $sRet "pt-PT";
  7995.         elseif($locale == 'sv')
  7996.             $sRet "sv-SE";
  7997.         elseif($locale == 'uk')
  7998.             $sRet "uk-UA";
  7999.         elseif($locale == 'zu')
  8000.             $sRet "zu-ZA";
  8001.         elseif($locale == 'sr')
  8002.             $sRet "sr-RS";
  8003.         elseif($locale == 'ml')
  8004.             $sRet "ml-IN";
  8005.         elseif($locale == 'tl')
  8006.             $sRet "fil-PH";    
  8007.         elseif($locale == 'ru')
  8008.             $sRet "ru-RU";
  8009.         elseif($locale == 'ja')
  8010.             $sRet "ja-JP";                        
  8011.                 
  8012.         return $sRet;
  8013.     }
  8014.     
  8015.     function getLanguageListForSermonStorehouse()
  8016.     {            
  8017.         $sSql "select id, (case when nativename is not null and nativename <> '' then nativename else name end) as name from language where id in (select distinct language_id from lncsermon where language_id is not null and publish and type_id = " $this->LNCSERMON_TYPE_ID_PUBLIC ")";                
  8018.         $sSql .= " order by name";
  8019. //    echo $sSql . "<br>";            
  8020.         return $this->getNativeQueryResults($sSql);
  8021.     }
  8022.     
  8023.     function getTopicListForSermonStorehouse()
  8024.     {            
  8025.         $sSql "select id, description as name from lnctopic where id in (select distinct topic_id from lncsermon_topic where lncsermon_id in (select id from lncsermon where type_id = " $this->LNCSERMON_TYPE_ID_PUBLIC "))";                
  8026.         $sSql .= " order by name";
  8027. //    echo $sSql . "<br>";            
  8028.         return $this->getNativeQueryResults($sSql);
  8029.     }
  8030.     
  8031.     function getAuthorListForSermonStorehouse()
  8032.     {            
  8033.         $sSql "select id, name from vpersonforcombo where id in (select distinct person_id from lncsermon_person where lncsermon_id in (select id from lncsermon where type_id = " $this->LNCSERMON_TYPE_ID_PUBLIC "))";                
  8034.         $sSql .= " order by name";
  8035. //    echo $sSql . "<br>";            
  8036.         return $this->getNativeQueryResults($sSql);
  8037.     }
  8038.     
  8039.     function isBibleFullChapter($startverse_id$endverse_id)
  8040.     {
  8041.         $bRet false;
  8042.         $sSql1 "select cv1.ordering as order1, cv2.ordering as order2, cv1.chapter_id FROM canonicalbibleverse cv1, canonicalbibleverse cv2 where cv1.id = " $startverse_id " and cv2.id = " $endverse_id;
  8043.    // echo $sSql1."<br>";    
  8044.         $aData $this->getRowData($sSql1);        
  8045.         if(!empty($aData))
  8046.         {                    
  8047.             $startverse_order trim($aData['order1']); 
  8048.             $endverse_order trim($aData['order2']); 
  8049.             $chapter_id trim($aData['chapter_id']);
  8050.             
  8051.             $sSql2 "select min(cv.ordering) as min_order, max(cv.ordering) as max_order FROM canonicalbibleverse cv where chapter_id = " $chapter_id;
  8052.     //    echo $sSql2."<br>";        
  8053.             $aData2 $this->getRowData($sSql2);        
  8054.             if(!empty($aData2))
  8055.             {
  8056.                 $min_order trim($aData2['min_order']); 
  8057.                 $max_order trim($aData2['max_order']); 
  8058.                 $bRet = ($startverse_order == $min_order && $endverse_order == $max_order);
  8059.             }
  8060.         }    
  8061.         
  8062.         return $bRet;
  8063.     }
  8064.                         
  8065.     function getMynoteList($nStartNum$locale$request)
  8066.     {        
  8067.         $aRet = array();
  8068.         
  8069.         $nUserID $this->getCurrUserID($request);
  8070.         if(empty($nUserID))
  8071.         {
  8072.             return $this->getEmptyResult();
  8073.         }
  8074.    //     $nMaxResult = 400;
  8075.            $searchOptions $request->query->all();
  8076.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  8077.         $sBoundary $this->getBoundaryStrForSql($nLanguageID);
  8078.         
  8079.         $searchFor "";
  8080.         if(array_key_exists('searchTerm'$searchOptions))
  8081.         {
  8082.             $searchFor $searchOptions["searchTerm"];
  8083.             $searchFor $this->fixQuotes($searchFor);
  8084.         }
  8085.                  
  8086.         $sSql "SELECT id, text, url, link_text, linktype_id"
  8087.         $sSql .= " FROM user_note";
  8088.         $sSql .= " where user_id = " $nUserID
  8089.          
  8090.         $sFilter "";
  8091.         if(!empty($searchFor))
  8092.         {
  8093.              $sFilter .= " and (text ~* '" $sBoundary str_replace("'""''"$searchFor) . $sBoundary "' or link_text ~* '" $sBoundary str_replace("'""''"$searchFor) . $sBoundary "')";           
  8094.         }    
  8095.                 
  8096.         $sSql .= $sFilter;            
  8097.                  
  8098.         $sSql .= " order by id desc";
  8099.    //     $sSql .= " LIMIT ". $nMaxResult; 
  8100.         if($nStartNum 1)
  8101.         {            
  8102.             $sSql .= " OFFSET " $nStartNum;
  8103.         }   
  8104.              
  8105. //       echo $sSql . "<br>";  
  8106.           $results $this->getNativeQueryResults($sSql);
  8107.           $nResultCount count($results);
  8108.           if($nResultCount 0)
  8109.           {
  8110.               $nMaxTextLen 250;
  8111.               for($i=0;$i<$nResultCount;$i++)
  8112.               {
  8113.                   $nID $results[$i]['id'];
  8114.                   $sText $results[$i]['text'];
  8115.                   if(strlen($sText) > $nMaxTextLen)
  8116.                   {
  8117.                       $sTempText substr($sText0$nMaxTextLen);
  8118.                       $nPos $nMaxTextLen;
  8119.                       if(!empty($sBoundary))
  8120.                       {
  8121.                           $nPos strrpos($sTempText" ");
  8122.                       }
  8123.                       
  8124.                       $sNewText substr($sText0$nPos) . "<a id='link" $nID "' href='javascript:opentag(" $nID ")'>...</a><span id='tag" $nID "' style='display:none;'>" substr($sText$nPos) . "</span>";
  8125.                       
  8126.                       $results[$i]['text'] = $sNewText;
  8127.                   }
  8128.               }
  8129.           }
  8130.           
  8131.         $aRet['results'] = $results
  8132.                  
  8133.         $nTotalNum count($results);
  8134.     //    $bHasMore = (count($results) >= $nMaxResult);
  8135.         $bHasMore false;
  8136.         $bHasFilter = ($sFilter != '');           
  8137.         $aRet['total_record'] = $nTotalNum;
  8138.         $aRet['has_more'] = $bHasMore;
  8139.         $aRet['start_num'] = $nStartNum;
  8140.         $aRet['has_filter'] = $bHasFilter;
  8141.         return $aRet;
  8142.     }
  8143.     
  8144.     function getMyBookmarkList($nStartNum$locale$request)
  8145.     {        
  8146.         $aRet = array();
  8147.         
  8148.         $nUserID $this->getCurrUserID($request);
  8149.         if(empty($nUserID))
  8150.         {
  8151.             return $this->getEmptyResult();
  8152.         }
  8153.         
  8154.         $sBible $request->getSession()->get('ui_str')["linktype.header.bible"];
  8155.         $sTheology $request->getSession()->get('ui_str')["linktype.header.theology"];
  8156.         $sOther $request->getSession()->get('ui_str')["linktype.header.other"];
  8157.         
  8158.    //     $nMaxResult = 400;
  8159.            $searchOptions $request->query->all();
  8160.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  8161.         $sBoundary $this->getBoundaryStrForSql($nLanguageID);
  8162.         
  8163.         $searchFor "";
  8164.         if(array_key_exists('searchTerm'$searchOptions))
  8165.         {
  8166.             $searchFor $searchOptions["searchTerm"];
  8167.             $searchFor $this->fixQuotes($searchFor);
  8168.         }
  8169.                  
  8170.         $sSql "SELECT id, description, url, title as link_text, linktype_id, description, case when linktype_id = 1 then " $this->dbstr($sBible) . " else case when linktype_id = 2 then " $this->dbstr($sTheology) . " else " $this->dbstr($sOther) . " end end as linktype"
  8171.         $sSql .= " FROM user_bookmark";        
  8172.         $sSql .= " where user_id = " $nUserID
  8173.          
  8174.         $sFilter "";
  8175.         if(!empty($searchFor))
  8176.         {
  8177.              $sFilter .= " and (description ~* '" $sBoundary str_replace("'""''"$searchFor) . $sBoundary "' or title ~* '" $sBoundary str_replace("'""''"$searchFor) . $sBoundary "')";           
  8178.         }    
  8179.                                 
  8180.         $nTypeID "";
  8181.         if(array_key_exists('type'$searchOptions))
  8182.             $nTypeID $searchOptions['type'];
  8183.         
  8184.         if($nTypeID != '')
  8185.         {
  8186.              $sFilter .= " and linktype_id = " $nTypeID;             
  8187.         }    
  8188.                  
  8189.         $sSql .= $sFilter;            
  8190.                  
  8191.         $sSql .= " order by id desc";
  8192.    //     $sSql .= " LIMIT ". $nMaxResult; 
  8193.         if($nStartNum 1)
  8194.         {            
  8195.             $sSql .= " OFFSET " $nStartNum;
  8196.         }   
  8197.              
  8198.     //   echo $sSql . "<br>";  
  8199.           $results $this->getNativeQueryResults($sSql);
  8200.         $aRet['results'] = $results
  8201.                  
  8202.         $nTotalNum count($results);
  8203.     //    $bHasMore = (count($results) >= $nMaxResult);
  8204.         $bHasMore false;
  8205.         $bHasFilter = ($sFilter != '');           
  8206.         $aRet['total_record'] = $nTotalNum;
  8207.         $aRet['has_more'] = $bHasMore;
  8208.         $aRet['start_num'] = $nStartNum;
  8209.         $aRet['has_filter'] = $bHasFilter;
  8210.         return $aRet;
  8211.     }
  8212.     
  8213.     function getEmptyResult()
  8214.     {    
  8215.         $aRet = array();    
  8216.         $aRet['results'] = array();        
  8217.         $bHasFilter false;           
  8218.         $aRet['total_record'] = 0;
  8219.         $aRet['has_more'] = false;
  8220.         $aRet['start_num'] = 0;
  8221.         $aRet['has_filter'] = false;
  8222.         return $aRet;
  8223.     }
  8224.     
  8225.     function fixQuotes($str)
  8226.     {        
  8227.         $sRet trim($str"'");
  8228.         $sRet str_replace('"'""$sRet);
  8229.         return $sRet;
  8230.     }
  8231.     
  8232.     function dbstr($str)
  8233.     {        
  8234.         $sRet "'".str_replace("'""''"$str)."'";
  8235.         return $sRet;
  8236.     }
  8237.     
  8238.     function getLinkTypeList($request)
  8239.     {        
  8240.         $sBible $request->getSession()->get('ui_str')["linktype.header.bible"];
  8241.         $sTheology $request->getSession()->get('ui_str')["linktype.header.theology"];
  8242.         $sOther $request->getSession()->get('ui_str')["linktype.header.other"];
  8243.             
  8244.         $sSql "select id, case when id = 1 then " $this->dbstr($sBible) . " else case when id = 2 then " $this->dbstr($sTheology) . " else " $this->dbstr($sOther) . " end end as name from linktype";                
  8245.         $sSql .= " order by id";
  8246. //    echo $sSql . "<br>";            
  8247.         return $this->getNativeQueryResults($sSql);
  8248.     }
  8249.     
  8250.     function getFeaturedContentList($locale$vLimit$vUseDefaultLang=false)
  8251.     {             
  8252.         if($vUseDefaultLang)
  8253.             $nLanguageID $this->LANGUAGE_ID_ENGLISH;
  8254.         else
  8255.             $nLanguageID $this->getLanguageIDByShortCode($locale);
  8256.             
  8257.         $sSql "select * from (SELECT distinct on (t.id) t.translatedtitle AS title, t.description, t.url, bsw.story_id, bsw.story_url, t.url as translation_url, wo.feature_ordering, ";
  8258.         $sSql .= "case when fi.image_file is not null then fi.image_file else case when fi2.image_file is not null then fi2.image_file else case when ci.image_file is not null then ci.image_file else ti.image_file end end end as image_file, case when fi.image_file is not null then fi.image_title else case when fi2.image_file is not null then fi2.image_title else case when ci.image_file is not null then ci.image_title else ti.image_title end end end as image_title";
  8259.         $sSql .= " FROM expositionwork w, expositiontranslation t";
  8260.         // featured image from the current translation
  8261.         $sSql .= " left join (select distinct on (t1.id) t1.id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id) fi on t.id = fi.id";
  8262.         
  8263.         // featured image from the translation with image 
  8264.         $sSql .= " left join (select distinct on (t1.work_id) t1.work_id, i.file as image_file, i.title as image_title from expositiontranslation t1, image i where t1.is_featured and t1.feature_image_id = i.id order by t1.work_id, case when t1.language_id = " $this->LANGUAGE_ID_ENGLISH " then 1 else 2 end) fi2 on t.work_id = fi2.work_id";
  8265.         
  8266.         // textunit image
  8267.         $sSql .= " left join (select distinct on (tt1.translation_id) tt1.translation_id, i.file as image_file, i.title as image_title from textunit_image ti, image i, expositiontranslationtext tt1 where ti.textunit_id = tt1.placement_id and ti.image_id = i.id and i.mediatype_id = 1) ti on t.id = ti.translation_id";
  8268.         
  8269.         // For concepts
  8270.         $sSql .= " left join (select distinct on (cl.work_id) cl.work_id as id, i.file as image_file, i.title as image_title from image i, conceptillustration ci1, concept_work cl where cl.concept_id = ci1.concept_id and ci1.image_id = i.id) ci on t.work_id = ci.id";      
  8271.                 
  8272.         $sSql .= " join (select distinct on (t2.work_id) t2.work_id, t2.feature_ordering from expositiontranslation t2 where t2.is_featured and t2.language_id = " $this->LANGUAGE_ID_ENGLISH ") as wo on t.work_id = wo.work_id"
  8273.                 ." left join (select bs.id, bs.url as story_url, sw.work_id, sw.story_id from story_work sw, (select * from biblestory where level_id = " $this->STORY_LEVEL_ID_BIBLE ") as bs where bs.id = sw.story_id) bsw on t.work_id = bsw.work_id"
  8274.                 ." WHERE t.language_id = " $nLanguageID " AND t.ispublic AND w.ispublic and t.work_id=w.id"
  8275.                 $sSql .= " and w.id not IN (SELECT work_id FROM work_category WHERE category_id=" $this->CATEGORY_ID_DOCUMENTS ")";
  8276.                 $sSql .= " and t.id not IN (SELECT translation_id FROM translation_category WHERE category_id=" $this->CATEGORY_ID_DOCUMENTS ")";
  8277.                 $sSql .= ") as t1"
  8278.                 ." ORDER BY t1.feature_ordering";
  8279.                 
  8280.                 if($vLimit != null && $vLimit 0)
  8281.                  $sSql .= " limit " $vLimit;               
  8282.                
  8283. //  echo $sSql."<br>";      
  8284.         return $this->getNativeQueryResults($sSql);
  8285.     }
  8286.     
  8287.     // Check if the the translation has contents for a passage
  8288.     function getNewWorkTranslationUrl($translation_id$passage_id)
  8289.     {
  8290.         $sRet null;
  8291.         $sSql "select tt.id from expositiontranslationtext tt, expositiontextunit tu where tu.passage_id = " $passage_id " and tt.translation_id = " $translation_id " and tu.id = tt.placement_id limit 1";
  8292.         $nID $this->getSingleData($sSql);
  8293.         if(empty($nID))
  8294.         {
  8295.             $sSql2 "select url from (select distinct t.id, t.url from expositiondisplayitem di, expositiontranslationtext tt, expositiontextunit tu, expositiontranslation t where tu.passage_id = " $passage_id " and t.language_id in (select language_id from expositiontranslation where id = " $translation_id ") and tu.id = tt.placement_id and di.container_id = tt.id and t.id = tt.translation_id) as t order by t.id desc limit 1";
  8296.         //    echo $sSql2."<br>";
  8297.             $sUrl $this->getSingleData($sSql2);
  8298.             if(!empty($sUrl))
  8299.             {
  8300.                 $sSql2 "select swedenborgsection from expositionpassage where id = " $passage_id;
  8301.             //    echo $sSql2."<br>";
  8302.                 $nPassageOrder $this->getSingleData($sSql2);
  8303.                 if(!empty($nPassageOrder))
  8304.                 {
  8305.                     $sRet "swedenborg_" $sUrl "_" $nPassageOrder;
  8306.                 }
  8307.             }
  8308.         }        
  8309.         return $sRet;
  8310.     }
  8311.     
  8312.     function getLastAvailablePassageNum($translation_id)
  8313.     {
  8314.         $sSql "select p.swedenborgsection from expositiontranslationtext tt, expositiontextunit tu, expositionpassage p where tt.translation_id = " $translation_id " and tu.passage_id = p.id and tu.id = tt.placement_id order by p.ordering desc limit 1";
  8315.     //    echo $sSql."<br>";
  8316.         $nRet $this->getSingleData($sSql);
  8317.         return $nRet;
  8318.     }
  8319.     
  8320.     function getExplanationUrl($translation_id)
  8321.     {
  8322.         $sSql "SELECT '" $this->MULTI_URL_INDICATOR_EXPLANATION "_' || url as ref_column_spec"
  8323.                 ." FROM expositiontranslation"
  8324.                 ." WHERE id = " $translation_id;        
  8325.  //   echo $sSql."<br>";   
  8326.         return $this->getSingleData($sSql);
  8327.     }
  8328.     
  8329.     function getReadingPlanStepsForOutline($readingPlanUrl$UserID$request)
  8330.     {
  8331.         $locale $request->getLocale();    
  8332.         $nLanguageID $this->getLanguageIDByShortCode($locale);
  8333.         $sSql "";
  8334.         if(!empty($UserID))
  8335.         {
  8336.             $sSql "SELECT rs.id, rs.ordering, case when rsl.name is null then rs.name else rsl.name end as name, case when us.id is null then false else true end as is_completed, r.url FROM readingplan r, readingplanstep rs left join (select urs.* from user_readingplanstep urs, user_readingplan ur where ur.user_id = " $UserID " and ur.id = urs.user_readingplan_id) us on rs.id = us.readingplanstep_id  left join (select * from readingplanstep_language where language_id = " .$nLanguageID ") rsl on rs.id = rsl.readingplanstep_id" 
  8337.                 ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  8338.                 ." and r.id = rs.readingplan_id"                 
  8339.                  ." order by rs.ordering";
  8340.          }
  8341.          else
  8342.          {
  8343.              $sSql "SELECT rs.id, rs.ordering, case when rsl.name is null then rs.name else rsl.name end as name, false as is_completed, r.url FROM readingplan r, readingplanstep rs  left join (select * from readingplanstep_language where language_id = " .$nLanguageID ") rsl on rs.id = rsl.readingplanstep_id" 
  8344.                 ." where r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  8345.                 ." and r.id = rs.readingplan_id"                 
  8346.                  ." order by rs.ordering";
  8347.          }        
  8348. //   echo $sSql . "<br>";
  8349.         $aRet $this->getNativeQueryResults($sSql);
  8350.         return $aRet
  8351.     }
  8352.     
  8353.     function IsLastReadingPlanStep($vStepID$request)
  8354.     {                
  8355.         $bRet false;
  8356.         $nUserID $this->getCurrUserID($request);
  8357.         if(empty($nUserID))
  8358.         {
  8359.             return $bRet;
  8360.         }
  8361.         $sSql "select readingplan_id, ordering from readingplanstep where id = " $vStepID;    
  8362. // echo $sSql."<br>";
  8363.         $aStep $this->getRowData($sSql);
  8364.         $nReadingPlanID $aStep['readingplan_id'];
  8365.         $nStepOrder $aStep['ordering'];
  8366.                 
  8367.         $sSql "SELECT r.url as plan_url, rs.ordering as step_order"
  8368.                         ." FROM readingplan r, readingplanstep rs"
  8369.                         ." where r.id = " $nReadingPlanID
  8370.                         ." and r.id = rs.readingplan_id"                        
  8371.                         ." and rs.ordering > " $nStepOrder
  8372.                         ." order by rs.ordering limit 1";
  8373.   //   echo $sSql."<br>";   
  8374.            
  8375.         $aTemp $this->getNativeQueryResults($sSql);
  8376.         if(empty($aTemp)) 
  8377.             $bRet true;
  8378.                 
  8379.         return $bRet;   
  8380.     }
  8381.     
  8382.     function hasReadingPlanStarted($readingPlanUrl$UserID)
  8383.     {
  8384.         $bRet false;
  8385.         if(!empty($UserID))
  8386.         {
  8387.             $sSql "SELECT r.id FROM readingplan r, user_readingplan ur" 
  8388.                     ." where ur.user_id = " $UserID
  8389.                     ." and r.url = '" trim(str_replace("'""''"$readingPlanUrl)) . "'"
  8390.                     ." and r.id = ur.readingplan_id";
  8391.     //   echo $sSql . "<br>";             
  8392.             $aRet = array();
  8393.             $aTemp $this->getNativeQueryResults($sSql);
  8394.             if(count($aTemp) > 0
  8395.                 $bRet true;        
  8396.         }        
  8397.         return $bRet
  8398.     }
  8399.     
  8400.     function getRandomNum($length 6) {
  8401.         $sSeed '1234567890';
  8402.         $sRet '';
  8403.         $nSeedLen strlen($sSeed);
  8404.         for ($i 0$i $length$i++) {
  8405.             $sRet .= $sSeed[rand(0$nSeedLen 1)];
  8406.         }
  8407.         return $sRet;
  8408.     }
  8409. //--------
  8410. // For numbers less than 19 digits        
  8411.     function simpleEncrypt($num) {    
  8412.         return (intval($num)+$this->SC_SIMPLE_ENCRYPT_SEED)*$this->SC_SIMPLE_ENCRYPT_SEED;
  8413.     }
  8414.     
  8415.     function simpleDecrypt($num) {
  8416.         return (intval($num)/$this->SC_SIMPLE_ENCRYPT_SEED)-$this->SC_SIMPLE_ENCRYPT_SEED;
  8417.     }
  8418. //--------    
  8419. /*    function getStartedReadingPlanIDs($vUserID)
  8420.     {      
  8421.         $sSql = "select array_to_string(array_agg(readingplan_id),',') as IDs from user_readingplan where user_id = " . $vUserID;
  8422.   //   echo $sSql."<br>";  
  8423.           $sRet = $this->getSingleData($sSql);  
  8424.         return $sRet; 
  8425.     }*/
  8426.     
  8427.     function getReminderOptionList($request)
  8428.     {      
  8429.         $sOff $request->getSession()->get('ui_str')["readingplan.reminderoption.off"];
  8430.         $sDaily $request->getSession()->get('ui_str')["readingplan.reminderoption.daily"];
  8431.         $sWeekly $request->getSession()->get('ui_str')["readingplan.reminderoption.weekly"];
  8432.         
  8433.         $sSql "select id, case when id = 1 then " $this->dbstr($sOff) . " else case when id = 2 then " $this->dbstr($sDaily) . " else " $this->dbstr($sWeekly) . " end end as name from readingplanreminderoption order by id";
  8434.   //   echo $sSql."<br>";  
  8435.           $aRet $this->getListData($sSql);  
  8436.         return $aRet
  8437.     }
  8438.     
  8439.     function getChatHistoryList($vUserID$vLimit=null)
  8440.     {    
  8441.         $aRet = array();            
  8442.         $sSql "SELECT id, description, session, TO_CHAR(last_modify_time, 'mm/dd/yyyy') as datetime FROM chatbotthread";
  8443.         $sSql .= " WHERE id in (select distinct thread_id from chatbotmessage where user_id = " $vUserID ")";
  8444.         $sSql .= " order by last_modify_time desc"
  8445.         if(!empty($vLimit))
  8446.         {
  8447.             $sSql .= " limit " $vLimit;
  8448.         }        
  8449.  //    echo $sSql."<br>";   
  8450.            $aChat $this->getListData($sSql);             
  8451.         $aRet['chat_list'] = $aChat;
  8452.   /*      $nChatCount = count($aChat);
  8453.         $bShowMore = false;
  8454.         if((!empty($vLimit) && $nChatCount >= $vLimit) || $nChatCount > 0)
  8455.         {
  8456.             $sSql = "SELECT count(id) FROM chatbotthread";
  8457.             $sSql .= " WHERE id in (select distinct thread_id from chatbotmessage where user_id = " . $vUserID . ")";
  8458.             $nTotal = $this->getSingleData($sSql);            
  8459.             if(!empty($vLimit) && $nChatCount > $vLimit)
  8460.             {
  8461.                 $bShowMore = true;
  8462.             }
  8463.         }
  8464.         $aRet['show_more'] = $bShowMore; */
  8465.         
  8466.         return $aRet;
  8467.     }
  8468.     
  8469.     function hasSessionHistory($vSessionID)
  8470.     {                
  8471.         $sSql "SELECT id FROM chatbotthread";
  8472.         $sSql .= " WHERE session = " $vSessionID " limit 1";         
  8473.  //    echo $sSql."<br>";   
  8474.            $aRet $this->getListData($sSql);             
  8475.         return !empty($aRet);   
  8476.     }
  8477.     function hasChatHistory($vUserID)
  8478.     {                
  8479.         $sSql "SELECT t.id FROM chatbotthread t, chatbotmessage m where m.user_id = " $vUserID " and t.id = m.thread_id limit 1";        
  8480.  //    echo $sSql."<br>";   
  8481.            $aRet $this->getListData($sSql);             
  8482.         return !empty($aRet);   
  8483.     }
  8484. // end of php class