diff --git a/ActividadesWP/v5/galerias/index.php b/ActividadesWP/v5/galerias/index.php
new file mode 100644
index 0000000..aa106bd
--- /dev/null
+++ b/ActividadesWP/v5/galerias/index.php
@@ -0,0 +1,150 @@
+getConnection();
+
+ $galeria = new Galeria($db);
+
+ $stmt = $galeria->gallery_images($id);
+
+ $num = $stmt->rowCount();
+
+ if($num>0){
+ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
+ extract($row);
+
+ if($imagenes){
+ $ilist = unserialize($imagenes);
+ foreach($ilist as $i){
+ array_push($image_ids,$i);
+ }
+ }
+ if($sin_recortar){
+ $slist = unserialize($sin_recortar);
+ foreach($slist as $i){
+ array_push($image_ids,$i);
+ }
+ }
+
+ }
+ }
+
+ //Get all images from image_ids array
+ foreach($image_ids as $image){
+ $stmt = $galeria->image($image);
+ $num = $stmt->rowCount();
+ if($num>0){
+ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
+ extract($row);
+ array_push($images,unserialize($imagedata));
+ }
+ }
+ }
+
+ $data = array(
+ 'count' => count($images),
+ 'result' => array (
+ 'images' => $images
+ )
+ );
+
+ send_response( $data );
+ }
+
+ function gallery_list(){
+ $database = new Database();
+ $db = $database->getConnection();
+
+ $galeria = new Galeria($db);
+
+ $stmt = $galeria->gallery_list();
+
+ $num = $stmt->rowCount();
+
+ if($num>0){
+ $galleries_arr=array();
+
+ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
+ extract($row);
+
+ $response_item=array(
+ "title" => $post_title,
+ "id" => $ID,
+ "date" => $post_date,
+ "thumbnail" => $thumbnail
+ );
+
+ array_push($galleries_arr, $response_item);
+ }
+ }
+
+ $data = array(
+ 'count' => count($galleries_arr),
+ 'result' => array (
+ 'galleries' => $galleries_arr
+ )
+ );
+
+ send_response( $data );
+
+ }
+
+ function send_response( $data ){
+ // set response code - 200 OK
+ header('Content-Type: application/json; charset=utf-8');
+
+ http_response_code(200);
+
+ echo json_encode(
+ $data, JSON_UNESCAPED_UNICODE
+ );
+ }
\ No newline at end of file
diff --git a/ActividadesWP/v5/inc/actividad.php b/ActividadesWP/v5/inc/actividad.php
new file mode 100644
index 0000000..127cdaa
--- /dev/null
+++ b/ActividadesWP/v5/inc/actividad.php
@@ -0,0 +1,649 @@
+conn = $db;
+ }
+
+ /**
+ * Helper function to get all blogs and their languages
+ */
+ function get_blog_by_locale($locale){
+ $r = '';
+ switch($locale){
+ case "fr_FR":
+ case "fr":
+ $r = "wp_4_";
+ break;
+ case "en":
+ case "en_US":
+ $r = "wp_2_";
+ break;
+ case "pt":
+ case "pt-br":
+ case "pt_br":
+ case "pt_BR":
+ $r = "wp_3_";
+ break;
+ case "es":
+ case "es_ES":
+ default:
+ $r = "wp_";
+ break;
+ }
+ return $r;
+ }
+
+ function translation_slug( $locale, $id ){
+ $sql = "SELECT
+ P.post_name as slug
+ FROM wp_posts P
+ WHERE P.ID = $id";
+ return $this->execute_sql( $sql );
+ }
+
+
+ function translation_list( $year, $month, $last_update, $text, $locale, $termid="ultimas", $all=false, $history=false, $limit=16 ){ //Default last updated
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $sql = "SELECT
+ P.ID,
+ (SELECT
+ tt2.description AS translationmeta
+ FROM wp_posts P2
+ LEFT JOIN wp_term_relationships tr ON tr.object_id = P2.ID
+ LEFT JOIN wp_term_relationships tr2 ON tr2.object_id = P2.ID
+ LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'language'
+ INNER JOIN wp_term_taxonomy tt2 ON tr2.term_taxonomy_id = tt2.term_taxonomy_id AND tt2.taxonomy = 'post_translations'
+ LEFT JOIN wp_terms t ON t.term_id = tr.term_taxonomy_id
+ WHERE P2.ID=P.ID AND t.slug = '$locale') AS translationmeta,
+ P.post_title AS title,
+ P.post_date AS date,
+ P.post_modified AS modified,
+ P.post_name AS slug,
+ WEEKDAY(P.post_date) AS dia,
+ PMM.meta_value AS mensaje_id,
+ PMA.meta_value AS mensaje_json
+ FROM wp_posts P
+ LEFT JOIN wp_postmeta PMA ON PMA.post_id = P.ID AND PMA.meta_key = 'mensaje_json'
+ LEFT JOIN wp_postmeta PMM ON PMM.post_id = P.ID AND PMM.meta_key = 'mensaje'
+ INNER JOIN wp_terms T ON T.slug = '$locale'
+ INNER JOIN wp_term_relationships TR ON TR.object_id = P.ID AND TR.term_taxonomy_id = T.term_id
+ WHERE P.post_status = 'publish'
+ AND P.post_type = 'actividades'";
+ if($history){
+ $sql .= "
+ AND PMM.meta_value IS NOT NULL
+ AND PMM.meta_value != ''
+ AND PMA.meta_value IS NOT NULL
+ AND PMA.meta_value != ''";
+ }
+
+ if($year!=''){
+ $sql .= " AND YEAR(P.post_date) = '$year'";
+ if($month!=''){
+ $sql .= " AND MONTH(P.post_date) = '$month'";
+ }
+ if($last_update!=''){
+ $sql .= " AND UNIX_TIMESTAMP(P.post_modified) > ". $last_update;
+ }
+ $sql .= " ORDER BY P.post_date DESC";
+ } else {
+ $sql .= " ORDER BY P.post_date DESC";
+ if(!$all){
+if(!$limit){
+ $sql .= " LIMIT 16";
+} else {
+$sql .= " LIMIT " . $limit;
+}
+ }
+ }
+ return $this->execute_sql( $sql );
+ }
+
+ function activity_meta($id){
+ $sql = "SELECT
+PML.meta_value AS lugar,
+ PMC.meta_value AS city,
+ PMS.meta_value AS state,
+ PMCO.meta_value AS country,
+ PMT2.meta_value AS thumbnail,
+ PMN.meta_value AS numero_de_estudio_biblico,
+ PMA.meta_value AS actividad,
+ PMG.meta_value AS gallery,
+ PMY.meta_value AS youtube,
+ #PMU.meta_value AS url_del_mensaje,
+ PMI.meta_value AS mensaje,
+ PMJ.meta_value AS mensaje_json,
+ PMR.meta_value AS 'related_content',
+ PMRC.meta_value AS 'related_content_count',
+ PMCK.meta_value AS 'revisado'
+ FROM wp_posts P
+LEFT JOIN wp_postmeta PML ON P.ID = PML.post_id AND PML.meta_key = 'lugar'
+ LEFT JOIN wp_postmeta PMC ON P.ID = PMC.post_id AND PMC.meta_key = 'city'
+ LEFT JOIN wp_postmeta PMS ON P.ID = PMS.post_id AND PMS.meta_key = 'state'
+ LEFT JOIN wp_postmeta PMCO ON P.ID = PMCO.post_id AND PMCO.meta_key = 'country'
+ LEFT JOIN wp_postmeta PMA ON P.ID = PMA.post_id AND PMA.meta_key = 'actividad'
+ LEFT JOIN wp_postmeta PMN ON P.ID = PMN.post_id AND PMN.meta_key = 'numero_de_estudio_biblico'
+ LEFT JOIN wp_postmeta PMG ON P.ID = PMG.post_id AND PMG.meta_key = 'gallery'
+ LEFT JOIN wp_postmeta PMY ON P.ID = PMY.post_id AND PMY.meta_key = 'youtube'
+ #LEFT JOIN wp_postmeta PMU ON P.ID = PMU.post_id AND PMU.meta_key = 'url_del_mensaje'
+ LEFT JOIN wp_postmeta PMI ON P.ID = PMI.post_id AND PMI.meta_key = 'mensaje'
+ LEFT JOIN wp_postmeta PMJ ON P.ID = PMJ.post_id AND PMJ.meta_key = 'mensaje_json'
+ LEFT JOIN wp_postmeta PMT ON P.ID = PMT.post_id AND PMT.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMT2 ON PMT.meta_value = PMT2.post_id AND PMT2.meta_key = '_wp_attached_file'
+ LEFT JOIN wp_postmeta PMR ON P.ID = PMR.post_id AND PMR.meta_key = 'usar_contenido_relacionado'
+ LEFT JOIN wp_postmeta PMRC ON P.ID = PMRC.post_id AND PMRC.meta_key = 'contenido_relacionado'
+ LEFT JOIN wp_postmeta PMCK ON P.ID = PMCK.post_id AND PMCK.meta_key = 'revisado'
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'
+ AND P.ID = ".$id;
+ $data = $this->execute_sql( $sql );
+ $response = $data->fetch(PDO::FETCH_ASSOC);
+ return $response;
+ }
+
+ /**
+ * List function
+ *
+ * Displays the list of messages with it's pertinent variables
+ *
+ */
+ function activities_list( $year, $month, $last_update, $text, $locale ){
+ $sql = "SELECT
+ P.ID,
+ (SELECT
+ tt2.description AS translationmeta
+ FROM wp_posts P2
+ LEFT JOIN wp_term_relationships tr ON tr.object_id = P2.ID
+ LEFT JOIN wp_term_relationships tr2 ON tr2.object_id = P2.ID
+ LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'language'
+ INNER JOIN wp_term_taxonomy tt2 ON tr2.term_taxonomy_id = tt2.term_taxonomy_id AND tt2.taxonomy = 'post_translations'
+ LEFT JOIN wp_terms t ON t.term_id = tr.term_taxonomy_id
+ WHERE P2.ID='$id' AND t.slug = '$locale') AS translationmeta,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,";
+ if($text){
+ $sql .= "P.post_content as content,";
+ }
+ $sql .= "LENGTH(P.post_content) as bodylength,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ PMAS.meta_value AS meta,
+ #O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ LEFT JOIN wp_postmeta PMAS ON PM.meta_value = PMAS.post_id AND PMAS.meta_key = '_wp_attachment_metadata'
+ #LEFT JOIN wp_options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'";
+ if($year!=''){
+ $sql .= " AND YEAR(MD.date) = '$year'";
+ }
+ if($month!=''){
+ $sql .= " AND MONTH(MD.date) = '$month'";
+ }
+ if($last_update!=''){
+ $sql .= " AND UNIX_TIMESTAMP(P.post_modified) > ". $last_update;
+ }
+ $sql .= " ORDER BY P.post_date DESC";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Summary function
+ */
+ function summary($id,$locale){
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_name AS slug,
+ P.post_modified AS last_updated,
+ PMA.meta_value AS activity,
+ PML.meta_value AS lugar,
+ PMC.meta_value AS city,
+ PMS.meta_value AS state,
+ PMCO.meta_value AS country,
+ PMN.meta_value AS bible_study
+ FROM wp_posts P
+ LEFT JOIN wp_postmeta PMA ON PMA.post_id = P.ID AND PMA.meta_key = 'actividad'
+ LEFT JOIN wp_postmeta PML ON PML.post_id = P.ID AND PML.meta_key = 'lugar'
+ LEFT JOIN wp_postmeta PMC ON PMC.post_id = P.ID AND PMC.meta_key = 'city'
+ LEFT JOIN wp_postmeta PMS ON PMS.post_id = P.ID AND PMS.meta_key = 'state'
+ LEFT JOIN wp_postmeta PMCO ON PMCO.post_id = P.ID AND PMCO.meta_key = 'country'
+ LEFT JOIN wp_postmeta PMN ON PMN.post_id = P.ID AND PMN.meta_key = 'numero_de_estudio_biblico'
+ LEFT JOIN wp_postmeta PMPID ON PMPID.meta_key = 'mensaje' AND PMPID.meta_value = $id
+ WHERE P.ID = PMPID.post_id
+ AND P.post_status = 'publish'
+ AND P.post_type = 'actividades'";
+ return $this->execute_sql( $sql );
+ }
+
+
+ /**
+ * Detail function
+ *
+ * Given an ID returns the message with all details
+ *
+ * @param id Int id of the message whose details want to be found.
+ */
+ function detail($id,$locale){
+
+ $sql = "SELECT
+ P.ID,
+ (SELECT
+ tt2.description AS translationmeta
+ FROM wp_posts P2
+ LEFT JOIN wp_term_relationships tr ON tr.object_id = P2.ID
+ LEFT JOIN wp_term_relationships tr2 ON tr2.object_id = P2.ID
+ LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'language'
+ INNER JOIN wp_term_taxonomy tt2 ON tr2.term_taxonomy_id = tt2.term_taxonomy_id AND tt2.taxonomy = 'post_translations'
+ LEFT JOIN wp_terms t ON t.term_id = tr.term_taxonomy_id
+ WHERE P2.ID='$id' AND t.slug = '$locale') AS translationmeta,
+ P.post_title AS title,
+ P.post_content AS content,
+ P.post_date AS creation_date,
+ PMA.meta_value AS mensaje,
+ P.post_name AS slug,
+ P.post_modified AS last_updated
+ FROM wp_posts P
+ LEFT JOIN wp_postmeta PMA ON PMA.post_id = P.ID AND PMA.meta_key = 'mensaje'
+ WHERE P.ID = '$id' LIMIT 1";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Slug function
+ *
+ * Given a slug, returns the message with all details
+ *
+ * @param slug String Slug of the message whose details want to be found
+ */
+ function detailBySlug($slug,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ (SELECT
+ tt2.description AS translationmeta
+ FROM wp_posts P2
+ LEFT JOIN wp_term_relationships tr ON tr.object_id = P2.ID
+ LEFT JOIN wp_term_relationships tr2 ON tr2.object_id = P2.ID
+ LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'language'
+ INNER JOIN wp_term_taxonomy tt2 ON tr2.term_taxonomy_id = tt2.term_taxonomy_id AND tt2.taxonomy = 'post_translations'
+ LEFT JOIN wp_terms t ON t.term_id = tr.term_taxonomy_id
+ WHERE P2.post_name='$slug' AND t.slug = '$locale') AS translationmeta,
+ P.post_title AS title,
+ P.post_content AS content,
+ P.post_date AS creation_date,
+ P.post_name AS slug,
+ PMA.meta_value AS mensaje,
+ P.post_modified AS last_updated
+ FROM wp_posts P
+ LEFT JOIN wp_postmeta PMA ON PMA.post_id = P.ID AND PMA.meta_key = 'mensaje'
+ WHERE P.post_name='$slug'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Last update function
+ *
+ * Returns the last updated imtestamp for the message passed in via the @id
+ *
+ * @param id Int id for whom the last update should be found
+ */
+ function last_update($id){
+ $sql = "SELECT
+ P.post_modified AS last_updated
+ FROM wp_posts P
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Execute SQL function
+ *
+ * Executes a generic SQL statement and passes back the result.
+ *
+ * @param string sql SQl statement to be executed
+ * @return
+ */
+ function execute_sql( $sql ){
+ $stmt = $this->conn->prepare($sql);
+ $stmt->execute();
+ return $stmt;
+ }
+
+ /**
+ * Relevant conferences function
+ *
+ * Get all relevant conferences and return
+ */
+ function relevant_conferences(){
+ $sql = "SELECT
+ option_value
+ FROM wp_options
+ where option_name = 'options_conference'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_source($trid){
+ $sql = "SELECT
+ T.element_id AS post_id
+ FROM wp_icl_translations AS T
+ WHERE T.trid = '$trid'
+ AND T.language_code = 'es'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_interventions($id){
+ $sql = "SELECT
+ PM.meta_value
+ FROM wp_postmeta AS PM
+ WHERE PM.post_id = '$id'
+ AND PM.meta_key = 'intervenciones'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_interventions($id,$count){
+ $interventions = [];
+
+ for($i=0;$i<$count;$i++){
+ $sql = "SELECT
+ PMT.meta_value AS titulo,
+ PMF.meta_value AS fecha,
+ PML.meta_value AS lugar,
+ PMA.meta_value AS autor,
+ PMC.meta_value AS texto
+ FROM wp_postmeta AS PMT
+ LEFT JOIN wp_postmeta AS PMF ON PMF.post_id = '$id' AND PMF.meta_key = 'intervenciones_".$i."_fecha'
+ LEFT JOIN wp_postmeta AS PML ON PML.post_id = '$id' AND PML.meta_key = 'intervenciones_".$i."_lugar'
+ LEFT JOIN wp_postmeta AS PMA ON PMA.post_id = '$id' AND PMA.meta_key = 'intervenciones_".$i."_autor'
+ LEFT JOIN wp_postmeta AS PMC ON PMC.post_id = '$id' AND PMC.meta_key = 'intervenciones_".$i."_texto'
+ WHERE PMT.post_id = '$id'
+ AND PMT.meta_key = 'intervenciones_".$i."_titulo' ";
+ $data = $this->execute_sql( $sql );
+ $response = $data->fetch(PDO::FETCH_ASSOC);
+ //$interventions[$count] = $response;
+ array_push($interventions,$response);
+ }
+
+ return $interventions;
+ }
+
+ function get_related_content($id,$count){
+ $related = [];
+
+ for($i=0;$i<$count;$i++){
+ $sql = "SELECT
+ PM.meta_value AS conference_url
+ FROM wp_postmeta AS PM
+ WHERE PM.post_id = '$id'
+ AND PM.meta_key = 'contenido_relacionado_".$i."_conference_url'";
+ $data = $this->execute_sql( $sql );
+ $response = $data->fetch(PDO::FETCH_ASSOC);
+ array_push($related,$response);
+ }
+
+ return $related;
+ }
+
+ function get_post_language($id){
+ $sql = "SELECT
+ T.language_code,
+ T.trid
+ FROM wp_icl_translations AS T
+ WHERE T.element_id = '$id'
+ AND T.element_type = 'post_message'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_metadata($id){
+ $sql = "SELECT
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.country,
+ MD.state,
+ MD.city AS city,
+ MD.activity AS no_activity
+ FROM wp_messagedata AS MD
+ WHERE post_id = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_activity_files($id){
+ $sql = "SELECT
+ PMAR.meta_value AS use_files,
+ PMNV.meta_value AS videos,
+ PMNA.meta_value AS audios,
+ PMNT.meta_value AS textos,
+ PMNE.meta_value AS enlaces
+ FROM wp_posts P
+ LEFT JOIN wp_postmeta PMAR ON P.ID = PMAR.post_id AND PMAR.meta_key = 'usar_archivos'
+ LEFT JOIN wp_postmeta PMNV ON P.ID = PMNV.post_id AND PMNV.meta_key = 'videos'
+ LEFT JOIN wp_postmeta PMNA ON P.ID = PMNA.post_id AND PMNA.meta_key = 'audios'
+ LEFT JOIN wp_postmeta PMNT ON P.ID = PMNT.post_id AND PMNT.meta_key = 'textos'
+ LEFT JOIN wp_postmeta PMNE ON P.ID = PMNE.post_id AND PMNE.meta_key = 'enlaces'
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'
+ AND P.ID = ".$id;
+ return $this->execute_sql( $sql );
+ }
+
+ function get_files( $id, $type, $qty ){
+ $t = [];
+ for($x=0;$x<$qty;$x++){
+ $fileSql = $this->get_file_sql($id, $type, $x);
+ $data = $this->execute_sql( $fileSql );
+ $response = $data->fetch(PDO::FETCH_ASSOC);
+ array_push( $t, $response );
+ }
+ return $t;
+ }
+
+ function get_file_sql( $id, $type, $idx){
+ if($type == 'enlaces'){
+ $fname = 'enlace';
+ } else {
+ $fname = 'archivo';
+ }
+ $sql = "SELECT
+ PMAT.meta_value as title,
+ PMAD.meta_value as description,
+ PMAF.meta_value as link,
+ PF.guid AS file
+ FROM wp_posts P
+ LEFT JOIN wp_postmeta PMAT ON PMAT.post_id = P.ID AND PMAT.meta_key = '".$type."_".$idx."_titulo'
+ LEFT JOIN wp_postmeta PMAD ON PMAD.post_id = P.ID AND PMAD.meta_key = '".$type."_".$idx."_descripcion'
+ LEFT JOIN wp_postmeta PMAF ON PMAF.post_id = P.ID AND PMAF.meta_key = '".$type."_".$idx."_".$fname."'
+ LEFT JOIN wp_posts PF ON PF.ID = PMAF.meta_value
+ WHERE P.ID = $id";
+ return $sql;
+ }
+
+ function get_post_file($id,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.guid as url
+ FROM ".$prefix."posts P
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function title_search($q,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM ".$prefix."posts AS P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'
+ AND P.post_title LIKE('%$q%')";
+ return $this->execute_sql($sql);
+
+ }
+
+ function content_search($q){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ P.post_name as slug,
+ MATCH(P.post_content) AGAINST ('$q' IN NATURAL LANGUAGE MODE) as score,
+ SUBSTRING(P.post_content, LOCATE('$q', P.post_content) - 20, 300 + LENGTH('$q') + 300) as excerpt
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'
+ AND MATCH(P.post_content) AGAINST ('$q' IN NATURAL LANGUAGE MODE)
+ ORDER BY score DESC";
+ return $this->execute_sql($sql);
+ }
+
+ function country_summary(){
+ $sql = "SELECT
+ count( P.ID ) as total,
+ MC.country_name as country,
+ MC.country_code as country_code
+ FROM `wp_posts` P
+ INNER JOIN wp_messagedata MD ON MD.post_id = P.ID
+ INNER JOIN wp_messagecountries MC ON MC.country_code = MD.country
+ WHERE `post_status` = 'publish'
+ AND `post_type` = 'actividades'
+ AND MC.language_code = 'es'
+ GROUP BY country_code
+ ORDER BY country;";
+ return $this->execute_sql($sql);
+ }
+
+ function country_list($c){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ LENGTH(P.post_content) as bodylength,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ P.post_name as slug
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'
+ AND MD.country = '$c'
+ ORDER BY MD.date DESC";
+ return $this->execute_sql($sql);
+ }
+
+ function year_list( $locale ){
+ $sql = "SELECT
+ COUNT(P.ID) as total,
+ YEAR(P.post_date) as year,
+ MONTH(P.post_date) as month
+ FROM wp_posts P
+ INNER JOIN wp_terms T ON T.slug = '$locale'
+ INNER JOIN wp_term_relationships TR ON TR.object_id = P.ID AND TR.term_taxonomy_id = T.term_id
+ WHERE P.post_type = 'actividades' AND P.post_status = 'publish'
+ GROUP BY YEAR(P.post_date), MONTH(P.post_date)
+ ORDER BY YEAR(P.post_date) DESC, MONTH(P.post_date) DESC;";
+ return $this->execute_sql($sql);
+ }
+
+ function year_list_history( $locale ){
+ $sql = "SELECT
+ COUNT(P.ID) as total,
+ YEAR(P.post_date) as year,
+ MONTH(P.post_date) as month
+ FROM wp_posts P
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = 'mensaje_json'
+ INNER JOIN wp_terms T ON T.slug = 'es'
+ INNER JOIN wp_term_relationships TR ON TR.object_id = P.ID AND TR.term_taxonomy_id = T.term_id
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'
+ AND PM.meta_value IS NOT NULL
+ AND PM.meta_value != ''
+ GROUP BY YEAR(P.post_date), MONTH(P.post_date)
+ ORDER BY YEAR(P.post_date) DESC, MONTH(P.post_date) DESC;";
+ return $this->execute_sql($sql);
+ }
+
+ function lgccctv_list( $locale ){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ P.post_name as slug,
+ O.option_value AS translationmeta
+ FROM ".$prefix."posts P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'actividades'
+ AND P.post_status = 'publish'";
+
+ return $this->execute_sql( $sql );
+ }
+}
\ No newline at end of file
diff --git a/ActividadesWP/v5/inc/class-phpass.php b/ActividadesWP/v5/inc/class-phpass.php
new file mode 100644
index 0000000..8b8b113
--- /dev/null
+++ b/ActividadesWP/v5/inc/class-phpass.php
@@ -0,0 +1,276 @@
+ in 2004-2006 and placed in
+# the public domain. Revised in subsequent years, still public domain.
+#
+# There's absolutely no warranty.
+#
+# Please be sure to update the Version line if you edit this file in any way.
+# It is suggested that you leave the main version number intact, but indicate
+# your project name (after the slash) and add your own revision information.
+#
+# Please do not change the "private" password hashing method implemented in
+# here, thereby making your hashes incompatible. However, if you must, please
+# change the hash type identifier (the "$P$") to something different.
+#
+# Obviously, since this code is in the public domain, the above are not
+# requirements (there can be none), but merely suggestions.
+#
+
+/**
+ * Portable PHP password hashing framework.
+ *
+ * @package phpass
+ * @version 0.3 / WordPress
+ * @link http://www.openwall.com/phpass/
+ * @since 2.5.0
+ */
+class PasswordHash {
+ var $itoa64;
+ var $iteration_count_log2;
+ var $portable_hashes;
+ var $random_state;
+
+ /**
+ * PHP5 constructor.
+ */
+ function __construct( $iteration_count_log2, $portable_hashes )
+ {
+ $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+
+ if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
+ $iteration_count_log2 = 8;
+ $this->iteration_count_log2 = $iteration_count_log2;
+
+ $this->portable_hashes = $portable_hashes;
+
+ $this->random_state = microtime() . uniqid(rand(), TRUE); // removed getmypid() for compatibility reasons
+ }
+
+ /**
+ * PHP4 constructor.
+ */
+ public function PasswordHash( $iteration_count_log2, $portable_hashes ) {
+ self::__construct( $iteration_count_log2, $portable_hashes );
+ }
+
+ function get_random_bytes($count)
+ {
+ $output = '';
+ if ( @is_readable('/dev/urandom') &&
+ ($fh = @fopen('/dev/urandom', 'rb'))) {
+ $output = fread($fh, $count);
+ fclose($fh);
+ }
+
+ if (strlen($output) < $count) {
+ $output = '';
+ for ($i = 0; $i < $count; $i += 16) {
+ $this->random_state =
+ md5(microtime() . $this->random_state);
+ $output .=
+ pack('H*', md5($this->random_state));
+ }
+ $output = substr($output, 0, $count);
+ }
+
+ return $output;
+ }
+
+ function encode64($input, $count)
+ {
+ $output = '';
+ $i = 0;
+ do {
+ $value = ord($input[$i++]);
+ $output .= $this->itoa64[$value & 0x3f];
+ if ($i < $count)
+ $value |= ord($input[$i]) << 8;
+ $output .= $this->itoa64[($value >> 6) & 0x3f];
+ if ($i++ >= $count)
+ break;
+ if ($i < $count)
+ $value |= ord($input[$i]) << 16;
+ $output .= $this->itoa64[($value >> 12) & 0x3f];
+ if ($i++ >= $count)
+ break;
+ $output .= $this->itoa64[($value >> 18) & 0x3f];
+ } while ($i < $count);
+
+ return $output;
+ }
+
+ function gensalt_private($input)
+ {
+ $output = '$P$';
+ $output .= $this->itoa64[min($this->iteration_count_log2 +
+ ((PHP_VERSION >= '5') ? 5 : 3), 30)];
+ $output .= $this->encode64($input, 6);
+
+ return $output;
+ }
+
+ function crypt_private($password, $setting)
+ {
+ $output = '*0';
+ if (substr($setting, 0, 2) == $output)
+ $output = '*1';
+
+ $id = substr($setting, 0, 3);
+ # We use "$P$", phpBB3 uses "$H$" for the same thing
+ if ($id != '$P$' && $id != '$H$')
+ return $output;
+
+ $count_log2 = strpos($this->itoa64, $setting[3]);
+ if ($count_log2 < 7 || $count_log2 > 30)
+ return $output;
+
+ $count = 1 << $count_log2;
+
+ $salt = substr($setting, 4, 8);
+ if (strlen($salt) != 8)
+ return $output;
+
+ # We're kind of forced to use MD5 here since it's the only
+ # cryptographic primitive available in all versions of PHP
+ # currently in use. To implement our own low-level crypto
+ # in PHP would result in much worse performance and
+ # consequently in lower iteration counts and hashes that are
+ # quicker to crack (by non-PHP code).
+ if (PHP_VERSION >= '5') {
+ $hash = md5($salt . $password, TRUE);
+ do {
+ $hash = md5($hash . $password, TRUE);
+ } while (--$count);
+ } else {
+ $hash = pack('H*', md5($salt . $password));
+ do {
+ $hash = pack('H*', md5($hash . $password));
+ } while (--$count);
+ }
+
+ $output = substr($setting, 0, 12);
+ $output .= $this->encode64($hash, 16);
+
+ return $output;
+ }
+
+ function gensalt_extended($input)
+ {
+ $count_log2 = min($this->iteration_count_log2 + 8, 24);
+ # This should be odd to not reveal weak DES keys, and the
+ # maximum valid value is (2**24 - 1) which is odd anyway.
+ $count = (1 << $count_log2) - 1;
+
+ $output = '_';
+ $output .= $this->itoa64[$count & 0x3f];
+ $output .= $this->itoa64[($count >> 6) & 0x3f];
+ $output .= $this->itoa64[($count >> 12) & 0x3f];
+ $output .= $this->itoa64[($count >> 18) & 0x3f];
+
+ $output .= $this->encode64($input, 3);
+
+ return $output;
+ }
+
+ function gensalt_blowfish($input)
+ {
+ # This one needs to use a different order of characters and a
+ # different encoding scheme from the one in encode64() above.
+ # We care because the last character in our encoded string will
+ # only represent 2 bits. While two known implementations of
+ # bcrypt will happily accept and correct a salt string which
+ # has the 4 unused bits set to non-zero, we do not want to take
+ # chances and we also do not want to waste an additional byte
+ # of entropy.
+ $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+
+ $output = '$2a$';
+ $output .= chr(ord('0') + $this->iteration_count_log2 / 10);
+ $output .= chr(ord('0') + $this->iteration_count_log2 % 10);
+ $output .= '$';
+
+ $i = 0;
+ do {
+ $c1 = ord($input[$i++]);
+ $output .= $itoa64[$c1 >> 2];
+ $c1 = ($c1 & 0x03) << 4;
+ if ($i >= 16) {
+ $output .= $itoa64[$c1];
+ break;
+ }
+
+ $c2 = ord($input[$i++]);
+ $c1 |= $c2 >> 4;
+ $output .= $itoa64[$c1];
+ $c1 = ($c2 & 0x0f) << 2;
+
+ $c2 = ord($input[$i++]);
+ $c1 |= $c2 >> 6;
+ $output .= $itoa64[$c1];
+ $output .= $itoa64[$c2 & 0x3f];
+ } while (1);
+
+ return $output;
+ }
+
+ function HashPassword($password)
+ {
+ if ( strlen( $password ) > 4096 ) {
+ return '*';
+ }
+
+ $random = '';
+
+ if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
+ $random = $this->get_random_bytes(16);
+ $hash =
+ crypt($password, $this->gensalt_blowfish($random));
+ if (strlen($hash) == 60)
+ return $hash;
+ }
+
+ if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
+ if (strlen($random) < 3)
+ $random = $this->get_random_bytes(3);
+ $hash =
+ crypt($password, $this->gensalt_extended($random));
+ if (strlen($hash) == 20)
+ return $hash;
+ }
+
+ if (strlen($random) < 6)
+ $random = $this->get_random_bytes(6);
+ $hash =
+ $this->crypt_private($password,
+ $this->gensalt_private($random));
+ if (strlen($hash) == 34)
+ return $hash;
+
+ # Returning '*' on error is safe here, but would _not_ be safe
+ # in a crypt(3)-like function used _both_ for generating new
+ # hashes and for validating passwords against existing hashes.
+ return '*';
+ }
+
+ function CheckPassword($password, $stored_hash)
+ {
+ if ( strlen( $password ) > 4096 ) {
+ return false;
+ }
+
+ $hash = $this->crypt_private($password, $stored_hash);
+ if ($hash[0] == '*')
+ $hash = crypt($password, $stored_hash);
+
+ return $hash === $stored_hash;
+ }
+}
\ No newline at end of file
diff --git a/ActividadesWP/v5/inc/conferencia.php b/ActividadesWP/v5/inc/conferencia.php
new file mode 100644
index 0000000..16e07bc
--- /dev/null
+++ b/ActividadesWP/v5/inc/conferencia.php
@@ -0,0 +1,449 @@
+conn = $db;
+ }
+
+ /**
+ * Helper function to get all blogs and their languages
+ */
+ function get_blog_by_locale($locale){
+ $r = '';
+ switch($locale){
+ case "fr_FR":
+ case "fr":
+ $r = "wp_4_";
+ break;
+ case "en":
+ case "en_US":
+ $r = "wp_2_";
+ break;
+ case "pt":
+ case "pt-br":
+ case "pt_br":
+ case "pt_BR":
+ $r = "wp_3_";
+ break;
+ case "es":
+ case "es_ES":
+ default:
+ $r = "wp_";
+ break;
+ }
+ return $r;
+ }
+
+ function translation_list( $year, $month, $last_update, $text, $locale, $termid="ultimas" ){ //Default last updated
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ P.post_name as slug,";
+ if($text){
+ $sql .= "P.post_content as content,";
+ }
+ $sql .= "LENGTH(P.post_content) as bodylength,
+ O.option_value AS translationmeta
+ FROM ".$prefix."posts P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)";
+ if($year == '' && $month == ''){
+ $sql .= "
+ INNER JOIN ".$prefix."term_relationships AS tr ON (P.ID = tr.object_id)
+ INNER JOIN ".$prefix."terms AS t ON (t.term_id = tr.term_taxonomy_id)";
+ }
+ $sql .= "
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'";
+ if($year!=''){
+ $sql .= " AND YEAR(P.post_date) = '$year'";
+ if($month!=''){
+ $sql .= " AND MONTH(P.post_date) = '$month'";
+ }
+ if($last_update!=''){
+ $sql .= " AND UNIX_TIMESTAMP(P.post_modified) > ". $last_update;
+ }
+ $sql .= " ORDER BY P.post_date DESC";
+ } else {
+ $sql .= " AND t.slug = '$termid'";
+ $sql .= " ORDER BY P.post_modified DESC";
+ $sql .= " LIMIT 16";
+ }
+ return $this->execute_sql( $sql );
+ }
+
+ function conference_meta($id){
+ $sql = "SELECT
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ MD.private,
+ PMA.meta_value AS thumbnail,
+ PMAS.meta_value AS meta
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ LEFT JOIN wp_postmeta PMAS ON PM.meta_value = PMAS.post_id AND PMAS.meta_key = '_wp_attachment_metadata'
+ LEFT JOIN wp_options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND P.ID = ".$id;
+ $data = $this->execute_sql( $sql );
+ $response = $data->fetch(PDO::FETCH_ASSOC);
+ return $response;
+ }
+
+ /**
+ * List function
+ *
+ * Displays the list of messages with it's pertinent variables
+ *
+ */
+ function list( $year, $month, $last_update, $text, $locale ){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,";
+ if($text){
+ $sql .= "P.post_content as content,";
+ }
+ $sql .= "LENGTH(P.post_content) as bodylength,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ PMAS.meta_value AS meta,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ LEFT JOIN wp_postmeta PMAS ON PM.meta_value = PMAS.post_id AND PMAS.meta_key = '_wp_attachment_metadata'
+ LEFT JOIN wp_options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'";
+ if($year!=''){
+ $sql .= " AND YEAR(MD.date) = '$year'";
+ }
+ if($month!=''){
+ $sql .= " AND MONTH(MD.date) = '$month'";
+ }
+ if($last_update!=''){
+ $sql .= " AND UNIX_TIMESTAMP(P.post_modified) > ". $last_update;
+ }
+ $sql .= " ORDER BY P.post_date DESC";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Detail function
+ *
+ * Given an ID returns the message with all details
+ *
+ * @param id Int id of the message whose details want to be found.
+ */
+ function detail($id,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_content AS content,
+ P.post_date AS creation_date,
+ P.post_modified AS last_updated,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM ".$prefix."posts AS P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Slug function
+ *
+ * Given a slug, returns the message with all details
+ *
+ * @param slug String Slug of the message whose details want to be found
+ */
+ function detailBySlug($slug,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_content AS content,
+ P.post_date AS creation_date,
+ P.post_modified AS last_updated,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM ".$prefix."posts AS P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_name = '$slug'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Last update function
+ *
+ * Returns the last updated imtestamp for the message passed in via the @id
+ *
+ * @param id Int id for whom the last update should be found
+ */
+ function last_update($id){
+ $sql = "SELECT
+ P.post_modified AS last_updated
+ FROM wp_posts P
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Execute SQL function
+ *
+ * Executes a generic SQL statement and passes back the result.
+ *
+ * @param string sql SQl statement to be executed
+ * @return
+ */
+ function execute_sql( $sql ){
+ $stmt = $this->conn->prepare($sql);
+ $stmt->execute();
+ return $stmt;
+ }
+
+ /**
+ * Relevant conferences function
+ *
+ * Get all relevant conferences and return
+ */
+ function relevant_conferences(){
+ $sql = "SELECT
+ option_value
+ FROM wp_options
+ where option_name = 'options_conference'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_source($trid){
+ $sql = "SELECT
+ T.element_id AS post_id
+ FROM wp_icl_translations AS T
+ WHERE T.trid = '$trid'
+ AND T.language_code = 'es'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_language($id){
+ $sql = "SELECT
+ T.language_code,
+ T.trid
+ FROM wp_icl_translations AS T
+ WHERE T.element_id = '$id'
+ AND T.element_type = 'post_message'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_metadata($id){
+ $sql = "SELECT
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.country,
+ MD.state,
+ MD.city AS city,
+ MD.activity AS no_activity
+ FROM wp_messagedata AS MD
+ WHERE post_id = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_files($id,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ MF.youtube,
+ MF.video,
+ MF.audio,
+ MF.pdf,
+ MF.pdf_simple,
+ MF.videofile,
+ MF.audiofile,
+ MF.pdffile,
+ MF.pdfsimplefile
+ FROM ".$prefix."messagefiles as MF
+ WHERE MF.post_id = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_file($id,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.guid as url
+ FROM ".$prefix."posts P
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function title_search($q,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM ".$prefix."posts AS P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND P.post_title LIKE('%$q%')";
+ return $this->execute_sql($sql);
+
+ }
+
+ function content_search($q){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ P.post_name as slug,
+ MATCH(P.post_content) AGAINST ('$q' IN NATURAL LANGUAGE MODE) as score,
+ SUBSTRING(P.post_content, LOCATE('$q', P.post_content) - 20, 300 + LENGTH('$q') + 300) as excerpt
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND MATCH(P.post_content) AGAINST ('$q' IN NATURAL LANGUAGE MODE)
+ ORDER BY score DESC";
+ return $this->execute_sql($sql);
+ }
+
+ function country_summary(){
+ $sql = "SELECT
+ count( P.ID ) as total,
+ MC.country_name as country,
+ MC.country_code as country_code
+ FROM `wp_posts` P
+ INNER JOIN wp_messagedata MD ON MD.post_id = P.ID
+ INNER JOIN wp_messagecountries MC ON MC.country_code = MD.country
+ WHERE `post_status` = 'publish'
+ AND `post_type` = 'conferencias'
+ AND MC.language_code = 'es'
+ GROUP BY country_code
+ ORDER BY country;";
+ return $this->execute_sql($sql);
+ }
+
+ function country_list($c){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ LENGTH(P.post_content) as bodylength,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ P.post_name as slug
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND MD.country = '$c'
+ ORDER BY MD.date DESC";
+ return $this->execute_sql($sql);
+ }
+
+ function year_list(){
+ $sql = "SELECT
+ count(ID) as total,
+ YEAR(post_date) as year,
+ MONTH(post_date) as month
+ FROM wp_posts
+ WHERE `post_status` = 'publish'
+ AND `post_type` = 'conferencias'
+ GROUP BY YEAR(post_date), MONTH(post_date)
+ ORDER BY YEAR(post_date) DESC, MONTH(post_date) DESC;";
+ return $this->execute_sql($sql);
+ }
+
+ function lgccctv_list( $locale ){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ P.post_name as slug,
+ O.option_value AS translationmeta
+ FROM ".$prefix."posts P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'";
+
+ return $this->execute_sql( $sql );
+ }
+}
\ No newline at end of file
diff --git a/ActividadesWP/v5/inc/conferencia.php.old b/ActividadesWP/v5/inc/conferencia.php.old
new file mode 100644
index 0000000..4b30161
--- /dev/null
+++ b/ActividadesWP/v5/inc/conferencia.php.old
@@ -0,0 +1,429 @@
+conn = $db;
+ }
+
+ /**
+ * Helper function to get all blogs and their languages
+ */
+ function get_blog_by_locale($locale){
+ $r = '';
+ switch($locale){
+ case "fr_FR":
+ case "fr":
+ $r = "wp_4_";
+ break;
+ case "en":
+ case "en_US":
+ $r = "wp_2_";
+ break;
+ case "pt":
+ case "pt-br":
+ case "pt_br":
+ case "pt_BR":
+ $r = "wp_3_";
+ break;
+ case "es":
+ case "es_ES":
+ default:
+ $r = "wp_";
+ break;
+ }
+ return $r;
+ }
+
+ function translation_list( $year, $month, $last_update, $text, $locale, $termid="ultimas" ){ //Default last updated
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ P.post_name as slug,";
+ if($text){
+ $sql .= "P.post_content as content,";
+ }
+ $sql .= "LENGTH(P.post_content) as bodylength,
+ O.option_value AS translationmeta
+ FROM ".$prefix."posts P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)";
+ if($year == '' && $month == ''){
+ $sql .= "
+ INNER JOIN ".$prefix."term_relationships AS tr ON (P.ID = tr.object_id)
+ INNER JOIN ".$prefix."terms AS t ON (t.term_id = tr.term_taxonomy_id)";
+ }
+ $sql .= "
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'";
+ if($year!=''){
+ $sql .= " AND YEAR(P.post_date) = '$year'";
+ if($month!=''){
+ $sql .= " AND MONTH(P.post_date) = '$month'";
+ }
+ if($last_update!=''){
+ $sql .= " AND UNIX_TIMESTAMP(P.post_modified) > ". $last_update;
+ }
+ $sql .= " ORDER BY P.post_date DESC";
+ } else {
+ $sql .= " AND t.slug = '$termid'";
+ $sql .= " ORDER BY P.post_modified DESC";
+ $sql .= " LIMIT 16";
+ }
+ return $this->execute_sql( $sql );
+ }
+
+ function conference_meta($id){
+ $sql = "SELECT
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ PMAS.meta_value AS meta
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ LEFT JOIN wp_postmeta PMAS ON PM.meta_value = PMAS.post_id AND PMAS.meta_key = '_wp_attachment_metadata'
+ LEFT JOIN wp_options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND P.ID = ".$id;
+ $data = $this->execute_sql( $sql );
+ $response = $data->fetch(PDO::FETCH_ASSOC);
+ return $response;
+ }
+
+ /**
+ * List function
+ *
+ * Displays the list of messages with it's pertinent variables
+ *
+ */
+ function list( $year, $month, $last_update, $text, $locale ){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,";
+ if($text){
+ $sql .= "P.post_content as content,";
+ }
+ $sql .= "LENGTH(P.post_content) as bodylength,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ PMAS.meta_value AS meta,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ LEFT JOIN wp_postmeta PMAS ON PM.meta_value = PMAS.post_id AND PMAS.meta_key = '_wp_attachment_metadata'
+ LEFT JOIN wp_options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'";
+ if($year!=''){
+ $sql .= " AND YEAR(MD.date) = '$year'";
+ }
+ if($month!=''){
+ $sql .= " AND MONTH(MD.date) = '$month'";
+ }
+ if($last_update!=''){
+ $sql .= " AND UNIX_TIMESTAMP(P.post_modified) > ". $last_update;
+ }
+ $sql .= " ORDER BY P.post_date DESC";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Detail function
+ *
+ * Given an ID returns the message with all details
+ *
+ * @param id Int id of the message whose details want to be found.
+ */
+ function detail($id,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_content AS content,
+ P.post_date AS creation_date,
+ P.post_modified AS last_updated,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM ".$prefix."posts AS P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Slug function
+ *
+ * Given a slug, returns the message with all details
+ *
+ * @param slug String Slug of the message whose details want to be found
+ */
+ function detailBySlug($slug,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_content AS content,
+ P.post_date AS creation_date,
+ P.post_modified AS last_updated,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM ".$prefix."posts AS P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_name = '$slug'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Last update function
+ *
+ * Returns the last updated imtestamp for the message passed in via the @id
+ *
+ * @param id Int id for whom the last update should be found
+ */
+ function last_update($id){
+ $sql = "SELECT
+ P.post_modified AS last_updated
+ FROM wp_posts P
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ /**
+ * Execute SQL function
+ *
+ * Executes a generic SQL statement and passes back the result.
+ *
+ * @param string sql SQl statement to be executed
+ * @return
+ */
+ function execute_sql( $sql ){
+ $stmt = $this->conn->prepare($sql);
+ $stmt->execute();
+ return $stmt;
+ }
+
+ /**
+ * Relevant conferences function
+ *
+ * Get all relevant conferences and return
+ */
+ function relevant_conferences(){
+ $sql = "SELECT
+ option_value
+ FROM wp_options
+ where option_name = 'options_conference'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_source($trid){
+ $sql = "SELECT
+ T.element_id AS post_id
+ FROM wp_icl_translations AS T
+ WHERE T.trid = '$trid'
+ AND T.language_code = 'es'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_language($id){
+ $sql = "SELECT
+ T.language_code,
+ T.trid
+ FROM wp_icl_translations AS T
+ WHERE T.element_id = '$id'
+ AND T.element_type = 'post_message'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_metadata($id){
+ $sql = "SELECT
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.country,
+ MD.state,
+ MD.city AS city,
+ MD.activity AS no_activity
+ FROM wp_messagedata AS MD
+ WHERE post_id = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_files($id,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ MF.youtube,
+ MF.video,
+ MF.audio,
+ MF.pdf,
+ MF.pdf_simple,
+ MF.videofile,
+ MF.audiofile,
+ MF.pdffile,
+ MF.pdfsimplefile
+ FROM ".$prefix."messagefiles as MF
+ WHERE MF.post_id = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function get_post_file($id,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.guid as url
+ FROM ".$prefix."posts P
+ WHERE P.ID = '$id'";
+ return $this->execute_sql( $sql );
+ }
+
+ function title_search($q,$locale){
+ //Check locale and change accordingly to the right DB prefix for that locale
+ $prefix = $this->get_blog_by_locale( $locale );
+
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ O.option_value AS translationmeta,
+ P.post_name as slug
+ FROM ".$prefix."posts AS P
+ LEFT JOIN ".$prefix."options O ON O.option_name = CONCAT('msls_',P.ID)
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND P.post_title LIKE('%$q%')";
+ return $this->execute_sql($sql);
+
+ }
+
+ function content_search($q){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ P.post_name as slug,
+ MATCH(P.post_content) AGAINST ('$q' IN NATURAL LANGUAGE MODE) as score,
+ SUBSTRING(P.post_content, LOCATE('$q', P.post_content) - 20, 300 + LENGTH('$q') + 300) as excerpt
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND MATCH(P.post_content) AGAINST ('$q' IN NATURAL LANGUAGE MODE)
+ ORDER BY score DESC";
+ return $this->execute_sql($sql);
+ }
+
+ function country_summary(){
+ $sql = "SELECT
+ count( P.ID ) as total,
+ MC.country_name as country,
+ MC.country_code as country_code
+ FROM `wp_posts` P
+ INNER JOIN wp_messagedata MD ON MD.post_id = P.ID
+ INNER JOIN wp_messagecountries MC ON MC.country_code = MD.country
+ WHERE `post_status` = 'publish'
+ AND `post_type` = 'conferencias'
+ AND MC.language_code = 'es'
+ GROUP BY country_code
+ ORDER BY country;";
+ return $this->execute_sql($sql);
+ }
+
+ function country_list($c){
+ $sql = "SELECT
+ P.ID,
+ P.post_title AS title,
+ P.post_date AS creation_date,
+ P.post_modified as last_updated,
+ LENGTH(P.post_content) as bodylength,
+ IFNULL(NULLIF(TIME_TO_SEC(MD.duration), '' ), 0) AS duration,
+ MD.date,
+ MD.activity AS no_activity,
+ MD.city,
+ MD.country,
+ MD.state,
+ PMA.meta_value AS thumbnail,
+ P.post_name as slug
+ FROM wp_posts P
+ LEFT JOIN wp_messagedata MD ON P.id = MD.post_id
+ LEFT JOIN wp_postmeta PM ON PM.post_id = P.ID AND PM.meta_key = '_thumbnail_id'
+ LEFT JOIN wp_postmeta PMA ON PM.meta_value = PMA.post_id AND PMA.meta_key = '_wp_attached_file'
+ WHERE P.post_type = 'conferencias'
+ AND P.post_status = 'publish'
+ AND MD.country = '$c'
+ ORDER BY MD.date DESC";
+ return $this->execute_sql($sql);
+ }
+
+ function year_list(){
+ $sql = "SELECT
+ count(ID) as total,
+ YEAR(post_date) as year,
+ MONTH(post_date) as month
+ FROM wp_posts
+ WHERE `post_status` = 'publish'
+ AND `post_type` = 'conferencias'
+ GROUP BY YEAR(post_date), MONTH(post_date)
+ ORDER BY YEAR(post_date) DESC, MONTH(post_date) DESC;";
+ return $this->execute_sql($sql);
+ }
+}
\ No newline at end of file
diff --git a/ActividadesWP/v5/inc/country.php b/ActividadesWP/v5/inc/country.php
new file mode 100644
index 0000000..3c0ef4a
--- /dev/null
+++ b/ActividadesWP/v5/inc/country.php
@@ -0,0 +1,40 @@
+conn = $db;
+ }
+
+ // read products
+ function read( $lcode = 'es' ){
+
+ $last_update = '';
+
+ $sql = "SELECT
+ country_code,
+ country_name
+ FROM wp_messagecountries m
+ WHERE m.language_code = '$lcode'";
+
+ $stmt = $this->conn->prepare($sql);
+
+ // execute query
+ $stmt->execute();
+
+ return $stmt;
+ }
+}
diff --git a/ActividadesWP/v5/inc/db.php b/ActividadesWP/v5/inc/db.php
new file mode 100644
index 0000000..18bca43
--- /dev/null
+++ b/ActividadesWP/v5/inc/db.php
@@ -0,0 +1,30 @@
+conn = null;
+
+ try{
+ $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
+ $this->conn->exec("set names utf8");
+ }catch(PDOException $exception){
+ echo "Connection error: " . $exception->getMessage();
+ }
+
+ return $this->conn;
+ }
+
+ public function closeConnection(){
+ $this -> conn = null;
+ }
+}
\ No newline at end of file
diff --git a/ActividadesWP/v5/inc/epub/EPub.php b/ActividadesWP/v5/inc/epub/EPub.php
new file mode 100644
index 0000000..b95ded3
--- /dev/null
+++ b/ActividadesWP/v5/inc/epub/EPub.php
@@ -0,0 +1,1428 @@
+EPub requires Zip.php at version " . self::REQ_ZIP_VERSION . " or higher.
You can obtain the latest version from http://www.phpclasses.org/browse/package/6110.html.
processCSSExternalReferences for explanation. Default is EPub::EXTERNAL_REF_IGNORE.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root. NOT used if $externalReferences is set to EPub::EXTERNAL_REF_IGNORE.
+ *
+ * @return bool $success
+ */
+ function addCSSFile($fileName, $fileId, $fileData, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "") {
+ if ($this->isFinalized || array_key_exists($fileName, $this->fileList)) {
+ return FALSE;
+ }
+ $fileName = preg_replace('#\\\#i', "/", $fileName);
+ $fileName = preg_replace('#^[/\.]+#i', "", $fileName);
+
+ $cssDir = pathinfo($fileName);
+ $cssDir = preg_replace('#^[/\.]+#i', "", $cssDir["dirname"] . "/");
+ if (!empty($cssDir)) {
+ $cssDir = preg_replace('#[^/]+/#i', "../", $cssDir);
+ }
+
+ if ($externalReferences !== EPub::EXTERNAL_REF_IGNORE) {
+ $this->processCSSExternalReferences($fileData, $externalReferences, $baseDir, $cssDir);
+ }
+
+ $this->zip->addFile($fileData, $fileName);
+ $this->fileList[$fileName] = $fileName;
+ $this->opf_manifest .= "\t\tprocessChapterExternalReferences for explanation. Default is EPub::EXTERNAL_REF_IGNORE.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root. NOT used if $externalReferences is set to EPub::EXTERNAL_REF_IGNORE.
+ * @return bool $success
+ */
+ function addChapter($chapterName, $fileName, $chapterData, $autoSplit = FALSE, $externalReferences = EPub::EXTERNAL_REF_IGNORE, $baseDir = "") {
+ if ($this->isFinalized) {
+ return FALSE;
+ }
+ $fileName = preg_replace('#\\\#i', "/", $fileName);
+ $fileName = preg_replace('#^[/\.]+#i', "", $fileName);
+
+ $htmlDir = pathinfo($fileName);
+ $htmlDir = preg_replace('#^[/\.]+#i', "", $htmlDir["dirname"] . "/");
+
+ $chapter = $chapterData;
+ if ($autoSplit && is_string($chapterData) && mb_strlen($chapterData) > $this->splitDefaultSize) {
+ $splitter = new EPubChapterSplitter();
+
+ $chapterArray = $splitter->splitChapter($chapterData);
+ if (count($chapterArray) > 1) {
+ $chapter = $chapterArray;
+ }
+ }
+
+ if (!empty($chapter) && is_string($chapter)) {
+ if ($externalReferences !== EPub::EXTERNAL_REF_IGNORE) {
+ $this->processChapterExternalReferences($chapter, $externalReferences, $baseDir, $htmlDir);
+ }
+
+ $this->zip->addFile($chapter, $fileName);
+ $this->fileList[$fileName] = $fileName;
+ $this->chapterCount++;
+ $this->opf_manifest .= "\t\t<img src="../images/image.png"/>
+ *
+ * $externalReferences determins how the function will handle external references.
+ *
+ * @param mixed $doc (referenced)
+ * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root.
+ * @param String $htmlDir The path to the parent HTML file's directory from the root of the archive.
+ *
+ * @return Bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
+ */
+ protected function processChapterExternalReferences(&$doc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "") {
+ if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
+ return FALSE;
+ }
+
+ $backPath = preg_replace('#[^/]+/#i', "../", $htmlDir);
+ $isDocAString = is_string($doc);
+ $xmlDoc = NULL;
+
+ if ($isDocAString) {
+ $xmlDoc = new DOMDocument();
+ @$xmlDoc->loadHTML($doc);
+ } else {
+ $xmlDoc = $doc;
+ }
+
+ $this->processChapterStyles($xmlDoc, $externalReferences, $baseDir, $htmlDir);
+ $this->processChapterLinks($xmlDoc, $externalReferences, $baseDir, $htmlDir, $backPath);
+ $this->processChapterImages($xmlDoc, $externalReferences, $baseDir, $htmlDir, $backPath);
+
+ if ($isDocAString) {
+ $html = $xmlDoc->saveXML();
+
+ $head = $xmlDoc->getElementsByTagName("head");
+ $body = $xmlDoc->getElementsByTagName("body");
+
+ $xml = new DOMDocument('1.0', "utf-8");
+ $xml->lookupPrefix("http://www.w3.org/1999/xhtml");
+ $xml->preserveWhiteSpace = FALSE;
+ $xml->formatOutput = TRUE;
+
+ $xml2Doc = new DOMDocument('1.0', "utf-8");
+ $xml2Doc->lookupPrefix("http://www.w3.org/1999/xhtml");
+ $xml2Doc->loadXML("\n\n\n\n");
+ $html = $xml2Doc->getElementsByTagName("html")->item(0);
+ $html->appendChild($xml2Doc->importNode($head->item(0), TRUE));
+ $html->appendChild($xml2Doc->importNode($body->item(0), TRUE));
+
+ // force pretty printing and correct formatting, should not be needed, but it is.
+ $xml->loadXML($xml2Doc->saveXML());
+ $doc = $xml->saveXML();
+ }
+ return TRUE;
+ }
+
+ /**
+ * Process images referenced from an CSS file to the book.
+ *
+ * $externalReferences determins how the function will handle external references.
+ *
+ * @param String $cssFile (referenced)
+ * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root.
+ * @param String $cssDir The of the CSS file's directory from the root of the archive.
+ *
+ * @return Bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
+ */
+ protected function processCSSExternalReferences(&$cssFile, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $cssDir = "") {
+ if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
+ return FALSE;
+ }
+
+ $backPath = preg_replace('#[^/]+/#i', "../", $cssDir);
+ preg_match_all('#url\s*\([\'\"\s]*(.+?)[\'\"\s]*\)#im', $cssFile, $imgs, PREG_SET_ORDER);
+
+ $itemCount = count($imgs);
+ for ($idx = 0; $idx < $itemCount; $idx++) {
+ $img = $imgs[$idx];
+ if ($externalReferences === EPub::EXTERNAL_REF_REMOVE_IMAGES || $externalReferences === EPub::EXTERNAL_REF_REPLACE_IMAGES) {
+ $cssFile = str_replace($img[0], "", $cssFile);
+ } else {
+ $source = $img[1];
+
+ $pathData = pathinfo($source);
+ $internalSrc = $pathData['basename'];
+ $internalPath = "";
+ $isSourceExternal = FALSE;
+
+ if ($this->resolveImage($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $cssDir, $backPath)) {
+ $cssFile = str_replace($img[0], "url('" . $backPath . $internalPath . "')", $cssFile);
+ } else if ($isSourceExternal) {
+ $cssFile = str_replace($img[0], "", $cssFile); // External image is missing
+ } // else do nothing, if the image is local, and missing, assume it's been generated.
+ }
+ }
+ return TRUE;
+ }
+
+ /**
+ * Process style tags in a DOMDocument. Styles will be passed as CSS files and reinserted into the document.
+ *
+ * @param DOMDocument $xmlDoc (referenced)
+ * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root.
+ * @param String $htmlDir The path to the parent HTML file's directory from the root of the archive.
+ *
+ * @return Bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
+ */
+ protected function processChapterStyles(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "") {
+ if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
+ return FALSE;
+ }
+ // process inlined CSS styles in style tags.
+ $styles = $xmlDoc->getElementsByTagName("style");
+ $styleCount = $styles->length;
+ for ($styleIdx = 0; $styleIdx < $styleCount; $styleIdx++) {
+ $style = $styles->item($styleIdx);
+ $styleData = $style->nodeValue;
+
+ $styleData = preg_replace('#[/\*\s]*\<\!\[CDATA\[[\s\*/]*#im', "", $styleData);
+ $styleData = preg_replace('#[/\*\s]*\]\]\>[\s\*/]*#im', "", $styleData);
+
+ $this->processCSSExternalReferences($styleData, $externalReferences, $baseDir, $htmlDir);
+ $style->nodeValue = "\n" . trim($styleData) . "\n";
+ }
+ return TRUE;
+ }
+
+ /**
+ * Process link tags in a DOMDocument. Linked files will be loaded into the archive, and the link src will be rewritten to point to that location.
+ * Link types text/css will be passed as CSS files.
+ *
+ * @param DOMDocument $xmlDoc (referenced)
+ * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root.
+ * @param String $htmlDir The path to the parent HTML file's directory from the root of the archive.
+ * @param String $backPath The path to get back to the root of the archive from $htmlDir.
+ *
+ * @return Bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
+ */
+ protected function processChapterLinks(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "", $backPath = "") {
+ if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
+ return FALSE;
+ }
+ // process link tags.
+ $links = $xmlDoc->getElementsByTagName("link");
+ $linkCount = $links->length;
+ for ($linkIdx = 0; $linkIdx < $linkCount; $linkIdx++) {
+ $link = $links->item($linkIdx);
+ $source = $link->attributes->getNamedItem("href")->nodeValue;
+ $sourceData = NULL;
+
+ $pathData = pathinfo($source);
+ $internalSrc = $pathData['basename'];
+
+ if (preg_match('#^(http|ftp)s?://#i', $source) == 1) {
+ $urlinfo = parse_url($source);
+
+ if (strpos($urlinfo['path'], $baseDir."/") !== FALSE) {
+ $internalSrc = substr($urlinfo['path'], strpos($urlinfo['path'], $baseDir."/") + strlen($basedir) + 1);
+ }
+
+ @$sourceData = file_get_contents($source);
+ } else if (strpos($source, "/") === 0) {
+ @$sourceData = file_get_contents($this->docRoot . $source);
+ } else {
+ @$sourceData = file_get_contents($this->docRoot . $baseDir . "/" . $source);
+ }
+
+ if (!empty($sourceData)) {
+ if (!array_key_exists($internalSrc, $this->fileList)) {
+ $mime = $link->attributes->getNamedItem("type")->nodeValue;
+ if (empty($mime)) {
+ $mime = "text/plain";
+ }
+ if ($mime == "text/css") {
+ $this->processCSSExternalReferences($sourceData, $externalReferences, $baseDir, $htmlDir);
+ $this->addCSSFile($internalSrc, $internalSrc, $sourceData, EPub::EXTERNAL_REF_IGNORE, $baseDir);
+ $link->setAttribute("href", $backPath . $internalSrc);
+ } else {
+ $this->addFile($internalSrc, $internalSrc, $sourceData, $mime);
+ }
+ $this->fileList[$internalSrc] = $source;
+ } else {
+ $link->setAttribute("href", $backPath . $internalSrc);
+ }
+ } // else do nothing, if the link is local, and missing, assume it's been generated.
+ }
+ return TRUE;
+ }
+
+ /**
+ * Process img tags in a DOMDocument.
+ * $externalReferences will determine what will happen to these images, and the img src will be rewritten accordingly.
+ *
+ * @param DOMDocument $xmlDoc (referenced)
+ * @param int $externalReferences How to handle external references, EPub::EXTERNAL_REF_IGNORE, EPub::EXTERNAL_REF_ADD or EPub::EXTERNAL_REF_REMOVE_IMAGES? Default is EPub::EXTERNAL_REF_ADD.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root.
+ * @param String $htmlDir The path to the parent HTML file's directory from the root of the archive.
+ * @param String $backPath The path to get back to the root of the archive from $htmlDir.
+ *
+ * @return Bool FALSE if uncuccessful (book is finalized or $externalReferences == EXTERNAL_REF_IGNORE).
+ */
+ protected function processChapterImages(&$xmlDoc, $externalReferences = EPub::EXTERNAL_REF_ADD, $baseDir = "", $htmlDir = "", $backPath = "") {
+ if ($this->isFinalized || $externalReferences === EPub::EXTERNAL_REF_IGNORE) {
+ return FALSE;
+ }
+ // process img tags.
+ $postProcDomElememts = array();
+ $images = $xmlDoc->getElementsByTagName("img");
+ $itemCount = $images->length;
+ for ($idx = 0; $idx < $itemCount; $idx++) {
+ $img = $images->item($idx);
+ if ($externalReferences === EPub::EXTERNAL_REF_REMOVE_IMAGES) {
+ $postProcDomElememts[] = $img;
+ } else if ($externalReferences === EPub::EXTERNAL_REF_REPLACE_IMAGES) {
+ $postProcDomElememts[] = array($img, $this->createDomFragment($xmlDoc, "[image]"));
+ } else {
+ $source = $img->attributes->getNamedItem("src")->nodeValue;
+
+ $pathData = pathinfo($source);
+ $internalSrc = $pathData['basename'];
+ $internalPath = "";
+ $isSourceExternal = FALSE;
+
+ if ($this->resolveImage($source, $internalPath, $internalSrc, $isSourceExternal, $baseDir, $htmlDir, $backPath)) {
+ $img->setAttribute("src", $backPath . $internalPath);
+ } else if ($isSourceExternal) {
+ $postProcDomElememts[] = $img; // External image is missing
+ } // else do nothing, if the image is local, and missing, assume it's been generated.
+ }
+ }
+
+ foreach ($postProcDomElememts as $target) {
+ if (is_array($target)) {
+ $target[0]->parentNode->replaceChild($target[1], $target[0]);
+ } else {
+ $target->parentNode->removeChild($target);
+ }
+ }
+ return TRUE;
+ }
+
+ /**
+ * Resolve an image src and determine it's target location and add it to the book.
+ *
+ * @param String $source Image Source link.
+ * @param String $internalPath (referenced) Return value, will be set to the target path and name in the book.
+ * @param String $internalSrc (referenced) Return value, will be set to the target name in the book.
+ * @param String $isSourceExternal (referenced) Return value, will be set to TRUE if the image originated from a full URL.
+ * @param String $baseDir Default is "", meaning it is pointing to the document root.
+ * @param String $htmlDir The path to the parent HTML file's directory from the root of the archive.
+ * @param String $backPath The path to get back to the root of the archive from $htmlDir.
+ */
+ protected function resolveImage($source, &$internalPath, &$internalSrc, &$isSourceExternal, $baseDir = "", $htmlDir = "", $backPath = "") {
+ if ($this->isFinalized) {
+ return FALSE;
+ }
+ $imageData = NULL;
+
+ if (preg_match('#^(http|ftp)s?://#i', $source) == 1) {
+ $urlinfo = parse_url($source);
+
+ if (strpos($urlinfo['path'], $baseDir."/") !== FALSE) {
+ $internalSrc = substr($urlinfo['path'], strpos($urlinfo['path'], $baseDir."/") + strlen($basedir) + 1);
+ }
+ $internalPath = $urlinfo["scheme"] . "/" . $urlinfo["host"] . "/" . pathinfo($urlinfo["path"], PATHINFO_DIRNAME);
+ $isSourceExternal = TRUE;
+ $imageData = $this->getImage($source);
+ } else if (strpos($source, "/") === 0) {
+ $internalPath = pathinfo($source, PATHINFO_DIRNAME);
+ $imageData = $this->getImage($this->docRoot . $source);
+ } else {
+ $internalPath = $htmlDir . "/" . preg_replace('#^[/\.]+#', '', pathinfo($source, PATHINFO_DIRNAME));
+ $imageData = $this->getImage($this->docRoot . $baseDir . "/" . $source);
+ }
+ if ($imageData !== FALSE) {
+ $internalPath = Zip::getRelativePath("images/" . $internalPath . "/" . $internalSrc);
+ if (!array_key_exists($internalPath, $this->fileList)) {
+ $this->addFile($internalPath, "i_" . $internalSrc, $imageData['image'], $imageData['mime']);
+ $this->fileList[$internalPath] = $source;
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /**
+ * Add a cover image to the book.
+ *
+ * The styling and structure of the generated XHTML is heavily inspired by the XHTML generated by Calibre.
+ *
+ * @param String $fileName Filename to use for the image, must be unique for the book.
+ * @param String $imageData Binary image data
+ * @param String $mimetype Image mimetype, such as "image/jpeg" or "image/png".
+ * @return bool $success
+ */
+ function setCoverImage($fileName, $imageData = NULL, $mimetype = NULL) {
+ if ($this->isFinalized || $this->isCoverImageSet || array_key_exists("CoverPage.html", $this->fileList)) {
+ return FALSE;
+ }
+
+ if ($imageData == NULL) { // assume $fileName is the valig file path.
+ $image = $this->getImage($this->docRoot . $fileName);
+ $imageData = $image['image'];
+ $mimetype = $image['mime'];
+ }
+ $path = pathinfo($this->docRoot . $fileName);
+ $imgPath = "images/" . $path["basename"];
+
+ $coverPage = "\n\n\t\n\t\t\n\t\tLength mismatch
\n"; + } + $this->streamFileLength += $length; + + return $length; + } + + /** + * Close the current stream. + * + * @return bool $success + */ + public function closeStream() { + if ($this->isFinalized || strlen($this->streamFilePath) == 0) { + return FALSE; + } + + fflush($this->streamData); + gzclose($this->streamData); + + $gzType = "\x08\x00"; // Compression type 8 = deflate + $gpFlags = "\x02\x00"; // General Purpose bit flags for compression type 8 it is: 0=Normal, 1=Maximum, 2=Fast, 3=super fast compression. + + $file_handle = fopen($this->streamFile, "rb"); + $stats = fstat($file_handle); + $eof = $stats['size']; + + fseek($file_handle, $eof-8); + $fileCRC32 = fread($file_handle, 4); + $dataLength = $this->streamFileLength;//$gzl[1]; + + $gzLength = $eof-10; + $eof -= 9; + + fseek($file_handle, 10); + + $this->buildZipEntry($this->streamFilePath, $this->streamFileComment, $gpFlags, $gzType, $this->streamTimestamp, $fileCRC32, $gzLength, $dataLength, 32); + while(!feof($file_handle)) { + fwrite($this->zipFile, fread($file_handle, $this->streamChunkSize)); + } + + unlink($this->streamFile); + $this->streamFile = NULL; + $this->streamData = NULL; + $this->streamFilePath = NULL; + $this->streamTimestamp = NULL; + $this->streamFileComment = NULL; + $this->streamFileLength = 0; + + return TRUE; + } + + /** + * Close the archive. + * A closed archive can no longer have new files added to it. + * + * @return bool $success + */ + public function finalize() { + if(!$this->isFinalized) { + if (strlen($this->streamFilePath) > 0) { + $this->closeStream(); + } + $cd = implode("", $this->cdRec); + + $cdRec = $cd . $this->endOfCentralDirectory + . pack("v", sizeof($this->cdRec)) + . pack("v", sizeof($this->cdRec)) + . pack("V", strlen($cd)) + . pack("V", $this->offset); + if (!is_null($this->zipComment)) { + $cdRec .= pack("v", strlen($this->zipComment)) . $this->zipComment; + } else { + $cdRec .= "\x00\x00"; + } + + if (is_null($this->zipFile)) { + $this->zipData .= $cdRec; + } else { + fwrite($this->zipFile, $cdRec); + fflush($this->zipFile); + } + $this->isFinalized = TRUE; + $cd = NULL; + $this->cdRec = NULL; + + return TRUE; + } + return FALSE; + } + + /** + * Get the handle ressource for the archive zip file. + * If the zip haven't been finalized yet, this will cause it to become finalized + * + * @return zip file handle + */ + public function getZipFile() { + if(!$this->isFinalized) { + $this->finalize(); + } + if (is_null($this->zipFile)) { + $this->zipFile = tmpfile(); + fwrite($this->zipFile, $this->zipData); + $this->zipData = NULL; + } + rewind($this->zipFile); + + return $this->zipFile; + } + + /** + * Get the zip file contents + * If the zip haven't been finalized yet, this will cause it to become finalized + * + * @return zip data + */ + public function getZipData() { + if(!$this->isFinalized) { + $this->finalize(); + } + if (is_null($this->zipFile)) { + return $this->zipData; + } else { + rewind($this->zipFile); + $filestat = fstat($this->zipFile); + return fread($this->zipFile, $filestat['size']); + } + } + + /** + * Send the archive as a zip download + * + * @param String $fileName The name of the Zip archive, ie. "archive.zip". + * @param String $contentType Content mime type. Optional, defailts to "application/zip". + * @return bool $success + */ + function sendZip($fileName, $contentType = "application/zip") { + if(!$this->isFinalized) { + $this->finalize(); + } + + if (!headers_sent($headerFile, $headerLine) or die("Error: Unable to send file $fileName. HTML Headers have already been sent from $headerFile in line $headerLine
")) { + if ((ob_get_contents() === FALSE || ob_get_contents() == '') or die("\nError: Unable to send file $fileName.epub. Output buffer contains the following text (typically warnings or errors):
" . ob_get_contents() . "