Преглед на файлове

Merge branch 'master' into Files

Iñigo Valentin преди 9 години
родител
ревизия
f05ed7893d

+ 4 - 1
.gitignore

@@ -14,18 +14,21 @@ Thumbs.db
 #Utility folders
 3rdparty/
 pending/
-utils/
+utils-local/
 copy
 remotecopy
+www-admin/redirect_s.php
 
 #SQL data
 sql/dbusers.sql
 sql/rows-test.sql
 sql/rows.sql
+sql/*201*
 
 #Passwords file
 www/.htpasswd
 www-admin/.htpasswd
+www/.htaccess_local
 
 #Photos and unnecessary images
 www/img/actividades/script

+ 60 - 0
README.es-ES.md

@@ -0,0 +1,60 @@
+---
+[Information in english](README.md) 
+[Informazioa euskaraz](README.es-EU.md)
+---
+
+# Web Gasteizko Margolariak #
+
+Código fuente de el sitio web de [Gasteizko Margolariak](https://margolariak.com/)
+
+Diseñado sobre Apache+MySQL+PHP.
+
+### Página pública ###
+
+La parte disponible al público es ligera, respetuosa con la privacidad del usuario e incluye:
+
+* Un blog de noticias en el que los usuarios pueden comentar.
+* Una galeria de imágenes con la que los usuarios pueden contribuir.
+* Informacion sobre las próximas actividades.
+* Reseñas de actividades pasadas.
+* Durante las Fiestas, informacion sobre las actividades y el programa de la cuadrilla.
+* Durante las Fiestass, información sobre los precios y las ofertas.
+* Localización en tiempo real de Gasteizko Margolariak.
+* Informacion sobre la cuadrilla.
+* Publicidad personaliza, no intrusiva, de los patrocinadores.
+* Una API para sincronizar aplicaciones propias o de terceros.
+* Recolección respetuosa de estadísticas.
+* Vanity URLs.
+
+
+### Página privada ###
+
+La parte privada del portal, reservada para administradores. Protegida por contraseña.
+
+Por ahora, incluye:
+
+* Un formulario para publicar, editar, borrar y traducir entradas del blog.
+* Un formulario para publicar, editar, borrar y traducir actividades.
+* Gestión de socios.
+* Formulario para confeccionar el programa de Fiestas.
+* Registro de actividad.
+
+Funcionalidades previstas:
+
+* Gestión de cuentas de usuario.
+* Gestión de la galería.
+* Visor de estadísticas.
+* Ajustes del sitio.
+* Borradores.
+* Otros.
+
+
+### Sobre este proyecto ###
+
+Se incluye el código fuente para la parte privada y la pública, así como scripts para construir la base de datos.
+
+
+### Aplicaciones ###
+
+* Tienes un iPhone? [Estamos en ellos!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakIOSApp) 
+* Android? [Lo tenemos!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakApp)

+ 60 - 0
README.es-EU.md

@@ -0,0 +1,60 @@
+---
+[Informacion en castellano](README.es-ES.md) 
+[Information in english](README.md)
+---
+
+# Web Gasteizko Margolariak #
+
+Código fuente de el sitio web de [Gasteizko Margolariak](https://margolariak.com/)
+
+Diseñado sobre Apache+MySQL+PHP.
+
+### Página pública ###
+
+La parte disponible al público es ligera, respetuosa con la privacidad del usuario e incluye:
+
+* Un blog de noticias en el que los usuarios pueden comentar.
+* Una galeria de imágenes con la que los usuarios pueden contribuir.
+* Informacion sobre las próximas actividades.
+* Reseñas de actividades pasadas.
+* Durante las Fiestas, informacion sobre las actividades y el programa de la cuadrilla.
+* Durante las Fiestass, información sobre los precios y las ofertas.
+* Localización en tiempo real de Gasteizko Margolariak.
+* Informacion sobre la cuadrilla.
+* Publicidad personaliza, no intrusiva, de los patrocinadores.
+* Una API para sincronizar aplicaciones propias o de terceros.
+* Recolección respetuosa de estadísticas.
+* Vanity URLs.
+
+
+### Página privada ###
+
+La parte privada del portal, reservada para administradores. Protegida por contraseña.
+
+Por ahora, incluye:
+
+* Un formulario para publicar, editar, borrar y traducir entradas del blog.
+* Un formulario para publicar, editar, borrar y traducir actividades.
+* Gestión de socios.
+* Formulario para confeccionar el programa de Fiestas.
+* Registro de actividad.
+
+Funcionalidades previstas:
+
+* Gestión de cuentas de usuario.
+* Gestión de la galería.
+* Visor de estadísticas.
+* Ajustes del sitio.
+* Borradores.
+* Otros.
+
+
+### Sobre este proyecto ###
+
+Se incluye el código fuente para la parte privada y la pública, así como scripts para construir la base de datos.
+
+
+### Aplicaciones ###
+
+* Tienes un iPhone? [Estamos en ellos!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakIOSApp) 
+* Android? [Lo tenemos!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakApp)

+ 14 - 7
README.md

@@ -1,11 +1,10 @@
-Gasteizko Margolariak Web
-===
+# Gasteizko Margolariak Web #
 
-Source code of the <a href="http://margolariak.com/">Gasteizko Margolariak</a> Web Portal.
+Source code of the [Gasteizko Margolariak](https://margolariak.com/) Web Portal.
 
 Website designed to work over Apache+MySQL+PHP.
 
-###Public page###
+### Public page ###
 
 The public page is available for anyone to visit, is respectfull with the privacy of the user, lightweight, and it includes:
 
@@ -18,12 +17,12 @@ The public page is available for anyone to visit, is respectfull with the privac
 * Real time location of Gasteizko Margolariak.
 * Information and the History of Gasteizko Margolariak.
 * Custom-made, non intrusive, privacy-awatre advertisment of collaborators.
-* An API to sync the <a href="https://github.com/GasteizkoMargolariak/GasteizkoMargolariakApp">App</a>.
+* An API to sync apps.
 * A respectfull statistics counter.
 * Vanity URLs.
 
 
-###Private page###
+### Private pag e###
 
 The private page includes a private area for the directives of Gasteizko Margolariak. It is designed to be served on a different port and is password protected.
 
@@ -44,6 +43,14 @@ In the future, more functionalities will be added:
 * Drafts.
 * Many more.
 
-###About this project###
+
+### About this project ###
 
 This projets includes the source for both the public and private page, as well as the files required to build the database. Apache configuration is left as an exercice to the reader.
+
+
+### On other devices ###
+
+* Got an iPhone? [We are working on it!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakIOSApp) 
+* Android? [Got you covered!](https://github.com/GasteizkoMargolariak/GasteizkoMargolariakApp)
+

+ 17 - 4
sql/setup.sql

@@ -333,11 +333,11 @@ CREATE TABLE festival_offer (
 DROP TABLE IF EXISTS location;
 CREATE TABLE location (
 	id		INT			AUTO_INCREMENT 	PRIMARY KEY,
-	action	VARCHAR(40)	NOT NULL,
+	action	VARCHAR(1)	NOT NULL,
 	dtime	TIMESTAMP	NOT NULL		DEFAULT now(),
-	lat		DOUBLE		NOT NULL,
-	lon		DOUBLE		NOT NULL,
-	manual	BOOLEAN		NOT NULL		DEFAULT 0,
+	lat		DOUBLE,
+	lon		DOUBLE,
+	start	INT,
 	user	INT			NOT NULL		REFERENCES user.id
 );
 
@@ -470,6 +470,19 @@ CREATE TABLE transact(
 	category		INT				NOT NULL	REFERENCES transac_category.id
 );
 
+DROP TABLE IF EXISTS translation;
+CREATE TABLE translation(
+	id				INT				AUTO_INCREMENT PRIMARY KEY,
+	dtime			TIMESTAMP		NOT NULL	DEFAULT now(),
+	username		VARCHAR(255)	NOT NULL	DEFAULT 'unknown',
+	tab				VARCHAR(255)	NOT NULL,
+	field			VARCHAR(255)	NOT NULL,
+	eid				INT				NOT NULL,
+	lang			VARCHAR(2)		NOT NULL,
+	text			VARCHAR(9000)	NOT NULL,
+	applied			DATETIME
+);
+
 #Set up two users for database. File dbusers.sql contains:
 /*
 GRANT SELECT ON gm.* TO 'XXXX'@'XXXX' IDENTIFIED BY 'XXXX';

+ 567 - 0
utils/GMSchedule.php

@@ -0,0 +1,567 @@
+ <?php
+		
+	function startdb(){
+		//Include the db configuration file. It's somehow like this
+		/*
+		<?php
+			$host = 'XXXX';
+			$db_name = 'XXXX';
+			$username_ro = 'XXXX';
+			$username_rw = 'XXXX';
+			$pass_ro = 'XXXX';
+			$pass_rw = 'XXXX';
+		?>
+		*/
+		include('.htpasswd');
+		
+		//Connect to to database
+		$con = mysqli_connect($host, $username_rw, $pass_rw, $db_name);
+		
+		//Set encoding options
+		mysqli_set_charset($con, 'utf-8');
+		header('Content-Type: text/html; charset=utf8');
+		mysqli_query($con, 'SET NAMES utf8;');
+		
+		//Return the db connection
+		return $con;
+	}	
+	
+?>
+
+<html>
+	<head>
+		<style>
+			@media print {
+				div#header, div.day, div.meetings{
+					page-break-after: always;
+				}
+				body{
+					background: #ffffff;
+					filter: initial;
+					font-size: 80%;
+					color: #ff0000;
+				}
+			}
+			@font-face{
+				font-family: font;
+				src: url('/font/FreeSans.ttf')
+			}
+			body{
+				font-family:		font;
+				margin:				2em;
+				/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#b5d3e5+0,e5f4ff+10,e5f4ff+90,b5d3e5+100 */
+				/*background: #b5d3e5; */
+				/*background: -moz-linear-gradient(left, #b5d3e5 0%, #e5f4ff 10%, #e5f4ff 90%, #b5d3e5 100%);*/ /* FF3.6-15 */
+				/*background: -webkit-linear-gradient(left, #b5d3e5 0%,#e5f4ff 10%,#e5f4ff 90%,#b5d3e5 100%);*/ /* Chrome10-25,Safari5.1-6 */
+				/*background: linear-gradient(to right, #b5d3e5 0%,#e5f4ff 10%,#e5f4ff 90%,#b5d3e5 100%);*/ /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
+				/*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b5d3e5', endColorstr='#b5d3e5',GradientType=1 );(/ /* IE6-9 */
+			}
+			div#header{
+				width: 100%;
+				text-align:	center;
+				margin-top: 18em;
+			}
+			div#header div#title{
+				display: inline;
+				vertical-align: middle;
+				width: 90%;
+				margin-top: 2em;
+				background-color: #0078ff;
+				color: #ffffff;
+				border-top-right-radius: 0.5em;
+				border-bottom-right-radius: 0.5em;
+				border: 0.3em solid #0045cc;
+				padding: 4em 4em 4em 0em;
+			}
+			div#header div#title img{
+				display: inline-block;
+				/*width: 6em;*/
+				/*height: 6em;*/
+				vertical-align: middle;
+				margin: -1em 1em -1em -2em;
+				-webkit-filter: drop-shadow(0 0 0.4em #dde);
+				filter: drop-shadow(0 0 0.4em #dde);
+				border: 0.1em solid #000011;
+				border-radius: 100%;
+				-ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=0, Color='#dde')";
+				filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=0, Color='#dde')";
+			}
+			div#header div#title h2{
+				display: inline-block;
+				font-size: 5em;
+				margin: 0.5em;
+				vertical-align: middle;
+			}
+			div#header h4{
+				display: inline-block;
+				margin: 1em auto 2em auto;
+				padding: 4em 2em 7em 2em;
+				color: #ffffff;
+                font-weight: bold;
+                font-size: 4em;
+				text-shadow: -0.02em 0 black, 0 0.02em black, 0.02em 0 black, 0 -0.02em #0045cc;
+				background: -moz-radial-gradient(center, ellipse cover, rgba(0,120,255,1) 10%, rgba(255,255,255,0) 67%, rgba(255,255,255,0) 100%); /* ff3.6+ */
+				background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(10%, rgba(0,120,255,1)), color-stop(67%, rgba(255,255,255,0)), color-stop(100%, rgba(255,255,255,0))); /* safari4+,chrome */
+				background:-webkit-radial-gradient(center, ellipse cover, rgba(0,120,255,1) 10%, rgba(255,255,255,0) 67%, rgba(255,255,255,0) 100%); /* safari5.1+,chrome10+ */
+				background: -o-radial-gradient(center, ellipse cover, rgba(0,120,255,1) 10%, rgba(255,255,255,0) 67%, rgba(255,255,255,0) 100%); /* opera 11.10+ */
+				background: -ms-radial-gradient(center, ellipse cover, rgba(0,120,255,1) 10%, rgba(255,255,255,0) 67%, rgba(255,255,255,0) 100%); /* ie10+ */
+				background:radial-gradient(ellipse at center, rgba(0,120,255,1) 10%, rgba(255,255,255,0) 67%, rgba(255,255,255,0) 100%); /* w3c */
+				filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0078ff', endColorstr='#ffffff',GradientType=1 ); /* ie6-9 */ 
+            }
+			div#header h3{
+				color: #ffffff;
+				font-weight: bold;
+				font-size: 5em;
+				text-shadow: -0.04em 0 #000033, 0 0.04em #000033, 0.04em 0 #000033, 0 -0.04em #000033;
+                display: inline-block;
+                margin: -8em auto 2em auto;
+			}
+			div#header span#warning{
+                color: #ff0000;
+                font-weight: bold;
+                font-size: 1.5em;
+                text-shadow: -0.04em 0 #000033, 0 0.04em #000033, 0.04em 0 #000033, 0 -0.04em #000033;
+                display: inline-block;
+                margin: -12em -7em 2em 7em;
+				-ms-transform: rotate(-30deg); /* IE 9 */
+				-webkit-transform: rotate(-30deg); /* Chrome, Safari, Opera */
+				transform: rotate(-30deg);
+            }
+			div#header table#contact{
+				color: #0056cc;
+				font-weight: bold;
+				margin: auto 0 auto auto;
+				/*text-shadow: -0.02em 0 #000000, 0 0.02em #000000, 0.02em 0 #000000, 0 -0.02em #000000;*/
+				/*text-shadow: -0.08em 0.3em black, 0.3em 0.08em black, 0.08em 0.3em black, 0.3em -0.08em #black;*/
+			}
+			div#header table#contact img{
+				height: 2em;
+				width: 2em;
+			}
+
+			div.tarifas table td{
+				vertical_align: middle;
+				border-top: 0.07em solid #999999;
+				padding: 1em;
+			}
+
+			div.tarifas table td.price{
+				text-align: right;
+				width: 4em;
+			}
+			div.tarifas table td.info{
+				padding-left: 4em;
+				color:initial;
+				text-align: center;
+			}
+			div.tarifas table td.warning{
+				padding-left: 4em;
+				color: red;
+				font-weight: bold;
+				text-align: center;
+			}
+
+			div.meetings td{
+				color: initial;
+				padding: 1em;
+			}
+
+
+			div.meetings table.location td.pinpoint{
+				width: 2em;
+			}
+
+			div.meetings table.location img{
+                margin-left: 1em;
+                margin-right: 0.5em;
+            }
+            div.meetings table.location span.place{
+                color: #444444;
+                font-size: 0.9em;
+            }
+            div.meetings span.address{
+                color: #666666;
+                margin-left: 0.5em;
+                font-style: italic;
+                font-size: 0.8em;
+			}
+
+			div.day,div.tarifas, div.meetings{
+				border-left: 0.1em solid #000011;
+				border-right: 0.1em solid #000011;
+				border-bottom: 0.1em solid #000011;
+				border-top-right-radius: 1em;
+				border-top-left-radius: 1em;
+				max-width:	80em;
+				margin: 2em auto 2em auto;
+				padding: 0 0 0.4em 0;
+				background-color: #0078ff;
+				-webkit-filter: drop-shadow(0 0 1em #0078ff);
+				filter: drop-shadow(0 0 1em #0078ff);
+				-ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=0, Color='#000011')";
+				filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=0, Color='#000011')";
+			}
+			div.day h3,div.tarifas h3, div.meetings h3{
+				font-size: 110%;
+				font-style: bold;
+				color: #ffffff;
+				background-color: #0078ff;
+				padding: 0.5em 2em 0.1em 1.5em;
+				border-top-left-radius: 0.7em;
+				border-top-right-radius: 0.7em;
+				border: 0.1em solid #000011;
+				margin: 0;
+			}
+			div.day table.day_content, div.tarifas table, div.meetings table{
+				width:	100%;
+				/*border-spacing: 10px;*/
+				border-collapse: collapse;
+				background-color: #ffffff;
+				margin: 0;
+			}
+			div.day table.day_content td{
+				padding: 0;
+			}
+			div.day table.day_content td.time{
+				width: 3em;
+				text-align: right;
+				color: #275573;
+				font-size: 1.2em;
+				font-weight: bold;
+				padding: 0.3em 0.5em 0.3em 0.3em;
+				vertical-align: top;
+				border-top: 0.07em solid #999999;
+			}
+			div.day table.day_content td.timeline{
+				text-align:center;
+				border-left: 0.2em dotted #999999;
+				border-top: 0.07em solid #999999;
+				vertical-align: top;
+			}
+			div.day table.day_content td.timeline img{
+				width: 1.1em;
+				height: 1.1em;
+				margin: 0.4em -1.4em 0 -1.4em;
+			}
+			div.day table.day_content td.info{
+				border-top: 0.07em solid #999999;
+				vertical-align: top;
+				padding: 0.3em 0.5em 0.3em 0.8em;
+			}
+			div.day table.day_content td.info h4, div.tarifas table td h4, div.meetings table td h4{
+				color: #275573;
+				/*letter-spacing: 0.07em;*/
+				font-size: 1.2em;
+				font-weight: bold;
+				margin:	0 0 0.2em 0em;
+			}
+			div.day table.day_content td.info p, div.tarifas table td span{
+				font-style: italic;
+				/*letter-spacing: 0.07em;*/
+				color: #222222;
+				font-size: 1em;
+				margin: 0 1em 0.5em 0.3em;
+			}
+			div.day table.day_content td.info table.location img{
+				margin-left: 1em;
+				margin-right: 0.5em;
+			}
+			div.day table.day_content td.info table.location span.place{
+				color: #444444;
+				font-size: 0.9em;
+			}
+			div.day table.day_content td.info table.location span.address{
+				color: #666666;
+				margin-left: 0.5em;
+				font-style: italic;
+				font-size: 0.8em;
+			}
+		</style>
+	</head>
+	<body>
+<?php
+		$con = startdb();
+	
+		$lang = strtolower($_GET['l']);
+		if ($lang != 'es' && $lang!= 'en' && $lang != 'eu'){
+			$lang = 'es';
+		}
+		
+		// TODO: Get current year
+		$year = 2017;
+?>
+		<div id='header'>
+			<div id='title'>
+				<img src='https://margolariak.com/img/logo/GasetizkoMargolariak.png' />
+				<h2>Gasteizko Margolariak</h2>
+			</div>
+<?php
+			switch($lang){
+				case 'eu':
+					$title = "Andre Maria Zuriaren jaiak egunetarako";
+					$warning = "";//"Behin-behineko !!";
+					break;
+				case 'en':
+					$title = "La Blanca Festivals schedule.";
+					$warning = "";//"Provisional !!";
+					break;
+				case 'es':
+					$title = "Programa Margolari<br/>Fiestas de La Blanca";
+					$warning = "";//"¡¡ Provisional !!";
+					break;
+			}
+?>
+			<br/>
+			<h4><?=$title?></h4>
+			<br/>
+			<h3><?=$year?></h3>
+			<br/>
+			<span id="warning"><?=$warning?></span>
+			<br/><br/><br/><br/><br/><br/><br/>
+			<table id='contact'>
+				<tr>
+					<td>
+						<img src='https://margolariak.com/img/social/whatsapp.png'/>
+					</td>
+					<td>
+						637 14 03 71
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<img src='https://margolariak.com/img/social/mail.png'/>
+					</td>
+					<td>
+						gasteizko@margolariak.com
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<img src='https://margolariak.com/img/social/twitter.png'/>
+					</td>
+					<td>
+						@gmargolariak
+					</td>
+				</tr>
+			</table>
+		</div>
+		<br/><br/>
+		<div class='tarifas'>
+<?php
+		$title = "";
+            switch($lang){
+                case 'es':
+					$title = "Tarifas y ofertas";
+					break;
+				case 'en':
+					$title = "Prices and offers";
+					break;
+				case 'eu':
+					$title = "Prezioak eta eskaintzak";
+			}
+?>
+			<h3><?=$title?></h3>
+				<table>
+<?php
+					$q_day = mysqli_query($con, "SELECT id, name_$lang AS name, DATE_FORMAT(date, '%e') AS day, DATE_FORMAT(date, '%c') AS month, price FROM festival_day WHERE date >= str_to_date('$year-00-00', '%Y-%m-%d') AND date <= str_to_date('$year-12-31', '%Y-%m-%d') ORDER BY date;");
+					while ($r = mysqli_fetch_array($q_day)){
+						$day = $r['day'];
+						$month_n = $r['month'];
+						$title = "";
+						switch($lang){
+							case 'es':
+								if ($month_n == '8'){
+									$title = "$day de agosto";
+								}
+								else{
+									$title = "$day de julio";
+								}
+								break;
+							case 'en':
+								if ($month_n == '8'){
+									$title = "August " . $day . "th";
+								}
+								else{
+									$title = "July " . $day . "th";
+								}
+								break;
+							case 'eu':
+								if ($month_n == '8'){
+									$title = "Abustuaren " . $day . "a";
+								}
+								else{
+									$title = "Uztailaren " . $day . "a";
+								}
+								break;
+						}
+?>
+						<tr>
+							<td>
+								<h4><?=$title?> - <?=$r['name']?></h4>
+							</td>
+							<td class='price'>
+								<h4><?=$r['price']?> €</h4>
+							</td>
+						</tr>
+<?php
+					}
+					$q_offer = mysqli_query($con, "SELECT name_$lang AS name, description_$lang AS description, price FROM festival_offer WHERE year = $year;");
+					while ($r = mysqli_fetch_array($q_offer)){
+?>
+						<tr>
+							<td>
+								<h4><?=$r['name']?></h4>
+								<span><?=$r['description']?></span>
+							</td>
+							<td class='price'>
+								<h4><?=$r['price']?> €</h4>
+							</td>
+						</tr>
+<?php
+					}
+?>
+					<tr>
+						<td class='info'>
+							Para apuntarte, solo tienes que hacer el ingreso correspondiente en la cuenta de Gasteizko Margolariak 
+							<br/><br/>
+							ES91 3035 0012 71 0120111936 de la Caja Laboral
+							<br/><br/>
+							indicando tu nombre y apellidos en el concepto. Si coges d&iacute;as sueltos o el pack de 3 d&iacute;as, deber&aacute;s indicar adem&aacute;s los d&iacute;as.
+						</td>
+						<td>
+						</td>
+					</tr>
+					<tr>
+						<td class='warning'>
+							¡Importante! El &uacute;ltimo d&iacute;a para realizar los ingresos es el 15 de julio.
+						</td>
+						<td>
+						</td>
+					</tr>
+				</table>
+		</div>
+		<br/><br/><br/><br/>
+		<div class='meetings'>
+<?php
+			$title = "";
+			switch($lang){
+				case 'es':
+					$title = "Reuniones";
+					break;
+				case 'en':
+					$title = "Meetings";
+					break;
+				case 'eu':
+					$title = "Bilerak";
+				}
+?>
+            <h3><?=$title?></h3>
+			<table>
+				<tr>
+					<td>
+						Antes de Fiestas, se organizar&aacute;n dos reuniones informativas, donde adem&aacute;s podr&aacute;s recoger las pulseras de control, parches, pines...
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<h4>Domingos 9 y 23 de julio, 20:00</h4>
+						<table class="location">
+								<tr>
+									<td class='pinpoint'><img src="https://margolariak.com/img/misc/pinpoint.png"></td>
+									<td>
+										<span class="place">Café Prado</span>
+										<br>
+										<span class="address">C/. Felicia Olave, S/N</span>
+									</td>
+								</tr>
+							</table>
+					</td>
+				</tr>
+
+			</table>
+		</div>
+<?php
+		// Gey day list
+		$q = mysqli_query($con, "SELECT id, name_$lang AS name, DATE_FORMAT(date, '%e') AS day, DATE_FORMAT(date, '%c') AS month FROM festival_day WHERE date >= str_to_date('$year-00-00', '%Y-%m-%d') AND date <= str_to_date('$year-12-31', '%Y-%m-%d') UNION SELECT 0, '' AS name, 10 AS day, 8 AS month FROM dual;");
+		while ($r = mysqli_fetch_array($q)){
+			$day = $r['day'];
+			$month_n = $r['month'];
+			$title = "";
+			switch($lang){
+				case 'es':
+					if ($month_n == '8'){
+						$title = "$day de agosto";
+					}
+					else{
+						$title = "$day de julio";
+					}
+					break;
+				case 'en':
+					if ($month_n == '8'){
+						$title = "August " . $day . "th";
+					}
+					else{
+						$title = "July " . $day . "th";
+					}
+					break;
+				case 'eu':
+					if ($month_n == '8'){
+						$title = "Abustuaren " . $day . "a";
+					}
+					else{
+						$title = "Uztailaren " . $day . "a";
+					}
+					break;
+			}
+			if (strlen($r['name']) > 0){
+				$title = "$title - $r[name]";
+			}
+
+?>
+			<br/><br/>
+			<div class='day'>
+				<h3><?=$title?></h3>
+				<table class='day_content'>
+<?php
+				$s_date = date_create_from_format('Y-m-d H:i', "$year-0" . $month_n . "-$day 07:00");
+				$e_date = date_create_from_format('Y-m-d H:i', "$year-0" . $month_n . "-$day 06:59");
+				$e_date = date_add($e_date, date_interval_create_from_date_string('1 days'));
+				$s_date = date_format($s_date, 'Y-m-d H:i');
+				$e_date = date_format($e_date, 'Y-m-d H:i');
+				$q_e = mysqli_query($con, "SELECT festival_event.id AS id, title_$lang AS title, description_$lang AS description, name_$lang AS place, address_$lang AS address, DATE_FORMAT(start, '%k:%i') AS time FROM festival_event, place WHERE place.id = place AND gm = 1 AND start >= str_to_date('$s_date', '%Y-%m-%d %H:%i') AND start <= str_to_date('$e_date', '%Y-%m-%d %H:%i') ORDER BY start;");
+				while ($r_e = mysqli_fetch_array($q_e)){
+?>
+					<tr>
+						<td class='time'><?=$r_e['time']?></td>
+						<td class='timeline'>
+							<img src='https://margolariak.com/img/misc/schedule-point.png'>
+						</td>
+						<td class='info'>
+							<h4><?=$r_e['title']?></h4>
+							<p><?=$r_e['description']?></p>
+							<table class='location'>
+								<tr>
+									<td><img src='https://margolariak.com/img/misc/pinpoint.png'/></td>
+									<td>
+										<span class='place'><?=$r_e['place']?></span>
+										<br/>
+										<span class='address'><?=$r_e['address']?></span>
+									</td>
+								</tr>
+							</table>
+						</td>
+					</tr>
+<?php
+				}
+?>
+			
+				</table> <!-- .day_content -->
+<?php			
+				//}
+?>
+			</div> <!-- .day -->
+<?php
+		}
+?>
+	</body>
+</html>

+ 6 - 0
utils/imgresize

@@ -0,0 +1,6 @@
+for file in *.jpg;do
+	convert "$file" -resize 800x800  "view/$file"
+	convert "$file" -resize 600x600  "preview/$file"
+	convert "$file" -resize 340x340  "miniature/$file"
+	convert "$file" -resize 180x180  "thumb/$file"
+done

+ 9 - 5
www-admin/css/lablanca.css

@@ -13,11 +13,6 @@ span.status_yellow{
 	color:			#ff8800;
 }
 
-div#entry_header{
-	display:	table-row;
-	padding:	0;
-}
-
 div#entry_header div.header_text{
 	display:		table-cell;
 	vertical-align:	top;
@@ -55,6 +50,15 @@ div#section_prices table#prices{
 	border-collapse:	collapse;
 }
 
+div#section_prices table#prices td, th{
+  border:	0.1em solid black;
+}
+
+div#section_prices table#prices table td, th{
+  border: 0;
+}
+
+
 div#section_prices table#prices input[type='text']{
 	max-width:	10em;
 }

+ 34 - 17
www-admin/lablanca/index.php

@@ -31,13 +31,27 @@
 		<?php include('../toolbar.php'); ?>
 		<div id='content'>
 			<div class='section' id='section_header'>
-				<h4>Paso 1: Cabecera de la p&aacute;gina de fiestas</h4>
+				<h3 class='section_title'>Paso 1: Cabecera de la p&aacute;gina de fiestas</h3>
 				<div class='entry status' id='status_header'>
 					...calculando...
 				</div>
 				<div class='entry' id='entry_header'>
-					<div class='header_text'>
-						Texto castellano:
+					<div id="lang_tabs">
+						<table>
+								<tr>
+									<td class="pointer lang_tabs_active" id="lang_tab_es" onclick="showLanguage('es');">
+										Castellano
+									</td>
+									<td class="pointer" id="lang_tab_eu" onclick="showLanguage('eu');">
+										Euskera
+									</td>
+									<td class="pointer" id="lang_tab_en" onclick="showLanguage('en');">
+										Ingl&eacute;s
+									</td>
+								</tr>
+						</table>
+					</div>
+					<div id="content_lang_es" class="festival_add_language">
 						<?php
 							$q = mysqli_query($con, "SELECT * FROM festival WHERE year = $year;");
 							$r = mysqli_fetch_array($q);
@@ -47,8 +61,7 @@
 							CKEDITOR.replace('text_es');
 						</script>
 					</div>
-					<div class='header_text'>
-						Texto ingl&eacute;s:
+					<div id="content_lang_en" class="festival_add_language" style="display:none;">
 						<?php
 							echo "<textarea id='text_en' onChange='updateField(\"festival\", \"text_en\", this.value, $r[id]);calculate(\"header\");'>$r[text_en]</textarea>\n";
 						?>
@@ -56,8 +69,7 @@
 							CKEDITOR.replace('text_en');
 						</script>
 					</div>
-					<div class='header_text'>
-						Texto euskera:
+					<div id="content_lang_eu" class="festival_add_language" style="display:none;">
 						<?php
 							echo "<textarea id='text_eu' onChange='updateField(\"festival\", \"text_eu\", this.value, $r[id]);calculate(\"header\");'>$r[text_eu]</textarea>\n";
 						?>
@@ -84,8 +96,9 @@
 					</div>
 				</div>
 			</div>
+			<br/><br/>
 			<div class='section' id='section_prices'>
-				<h4>Paso 2: Seleccionar precios:</h4>
+				<h3 class="section_title">Paso 2: Seleccionar precios:</h4>
 				<div class='entry status' id='status_prices'>
 					...calculando...
 				</div>
@@ -99,7 +112,7 @@
 						else{
 							echo "<h4>D&iacute;as sueltos:</h4>";
 							echo "<table id='prices'><tr><th>Fecha</th>";
-							echo "<th>Nombre<br/>castellano</th><th>Nombre<br/>ingl&eacute;s</th><th>Nombre<br/>euskera</th>";
+							echo "<th>Nombres</th>";
 							echo "<th>Precio</th></tr>\n";
 							$dates = ["25 Jul", "5 Ago", "6 Ago", "7 Ago", "8 Ago", "9 Ago"];
 							$i = 0;
@@ -117,11 +130,13 @@
 								else{
 									$eu = $r['name_eu'];
 								}
-								echo "</td>\n";
-								echo "<td><input type='text' value='$r[name_es]' onchange='updateField(\"festival_day\", \"name_es\", this.value, $r[id]);'/></td>\n";
-								echo "<td><input type='text' value='$en' onchange='updateField(\"festival_day\", \"name_en\", this.value, $r[id]);'/></td>\n";
-								echo "<td><input type='text' value='$eu' onchange='updateField(\"festival_day\", \"name_eu\", this.value, $r[id]);'/></td>\n";
-								echo "<td><input type='number' value='$r[price]' onchange='updateField(\"festival_day\", \"price\", this.value, $r[id], \"number\", false);'/>&euro;</td></tr>";
+								echo "</td><td>\n";
+								echo("<table>\n");
+								echo("<tr><td>Castellano:</td><td><input type='text' value='$r[name_es]' onchange='updateField(\"festival_day\", \"name_es\", this.value, $r[id]);'/></td></tr>\n");
+								echo("<tr><td>Euskera:</td><td><input type='text' value='$r[name_en]' onchange='updateField(\"festival_day\", \"name_en\", this.value, $r[id]);'/></td></tr>\n");
+								echo("<tr><td>Ingl&eacute;s:</td><td><input type='text' value='$r[name_eu]' onchange='updateField(\"festival_day\", \"name_eu\", this.value, $r[id]);'/></td></tr>\n");
+								echo("</table>\n");
+								echo "</td>\n<td>\n<input type='number' value='$r[price]' onchange='updateField(\"festival_day\", \"price\", this.value, $r[id], \"number\", false);'/>&euro;</td></tr>";
 								$i = $i + 1;
 							}
 							echo "</table>\n";
@@ -132,14 +147,14 @@
 					?>
 				</div>
 			</div>
-		
+			<br/><br/>
 			<div class='section' id='section_schedule'>
-				<h4>Paso 3: Establecer programa:</h4>
+				<h3 class='section_title'>Paso 3: Establecer programa:</h4>
 				<div class='entry status' id='status_schedule'>
 					...calculando...
 				</div>
 				<div class='entry entry_schedule' id='entry_schedule_25'>
-					<h4><img src='/img/misc/slid-right.png' onClick='expandSchedule(25);'/>25 de julio</h4>
+					<h3><img src='/img/misc/slid-right.png' onClick='expandSchedule(25);'/>25 de julio</h4>
 					<div id='list_schedule_25' class='list_schedule'>
 					</div>
 					Nuevo: 
@@ -203,6 +218,7 @@
 					</table>
 				</div>
 			</div>
+			<br/><br/>
 		</div>
 		<div id='screen_cover'></div>
 		<div id='form_new_offer' class='section'>
@@ -239,6 +255,7 @@
 				</div>
 			</div>
 		</div>
+		
 	</body>
 </html>
 <?php } ?>

+ 7 - 2
www/.htaccess

@@ -50,14 +50,19 @@ RewriteRule ^galeria/([A-Z\-a-z0-9{3,}]+)/$ /galeria/album.php?perm=$1 [NC]
 RewriteRule ^galeria/([A-Z\-a-z0-9{3,}]+)/([A-Z\-a-z0-9{3,}]+)$ /galeria/photo.php?album=$2&perm=$1 [NC]
 RewriteRule ^galeria/([A-Z\-a-z0-9{3,}]+)/([A-Z\-a-z0-9{3,}]+)/$ /galeria/photo.php?album=$2&perm=$1 [NC]
 
+RewriteRule ^traducir/eu$ /traducir/index.php?l=eu [NC]
+RewriteRule ^traducir/eu/$ /traducir/index.php?l=eu [NC]
+RewriteRule ^traducir/en$ /traducir/index.php?l=en [NC]
+RewriteRule ^traducir/en/$ /traducir/index.php?l=en [NC]
+
 #API redirections
 #TODO: This changes the url in the browser
 RewriteRule ^API/V([{0-9}]+)/help/([A-Z\-a-z0-9{3,}]+)$ /API/V$1/help/$2.php [NC,QSA,L]
 RewriteRule ^API/V([{0-9}]+)/help/([A-Z\-a-z0-9{3,}]+)/$ /API/V$1/help/$2.php [L,NC]
 
 #Force https TODO
-#RewriteCond %{HTTPS} !=on
-#RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
+RewriteCond %{HTTPS} !=on
+RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
 
 # BEGIN Cache-Control Headers
 <IfModule mod_expires.c>

+ 7 - 2
www/API/v1/location.php

@@ -60,10 +60,12 @@
 		//Bad request
 		http_response_code(400);
 		$error = $error . ERR_FORMAT . mysqli_real_escape_string($con, $_GET[GET_FORMAT]);
+		error_log($error);
+		exit(-1);
 	}
 	
 	//Get location
-	$q = mysqli_query($con, "SELECT lat, lon, dtime FROM location WHERE action = 'report' AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
+	$q = mysqli_query($con, "SELECT lat, lon, dtime FROM location WHERE action <> 'F' AND lat IS NOT null AND lon IS NOT null AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
 	if (mysqli_num_rows($q) > 0){
 		$r = mysqli_fetch_array($q);
 		switch ($format){
@@ -72,11 +74,14 @@
 				break;
 			default:
 				http_response_code(400);
-			$error = $error . ERR_FORMAT . mysqli_real_escape_string($con, $_GET[GET_FORMAT]);
+				$error = $error . ERR_FORMAT . mysqli_real_escape_string($con, $_GET[GET_FORMAT]);
+				error_log($error);
+				exit(-2);
 		}
 	}
 	else{
 		//No content
 		http_response_code(204);
+		exit(0);
 	}
 ?>

+ 9 - 9
www/API/v1/notifications.php

@@ -1,29 +1,29 @@
 <?php
 	// Gasteizko Margolariak API v1 //
-		
+
 	//List of available data formatting
 	define('FOR_JSON', 'json');
-	
+
 	//Default info format
 	define('DEF_FORMAT', FOR_JSON);
-	
+
 	//Posible notification target
 	define('TARGET_ALL', 'all');
 	define('TARGET_GM', 'gm');
-	
+
 	//Default target
 	define('DEF_TARGET', TARGET_ALL);
-		
+
 	//$_GET valid parameters
 	define('GET_CLIENT', 'client');
 	define('GET_USER', 'user');
 	define('GET_TARGET', 'target');
 	define('GET_FORMAT', 'json');
-	
+
 	//Error messages
 	define('ERR_TARGET', '-TARGET:');
 	define('ERR_FORMAT', '-FORMAT:');
-	
+
 	/****************************************************
 	* This function is called from almost everywhere at *
 	* the beggining of the page. It initializes the     *
@@ -120,8 +120,8 @@
 		http_response_code(400);
 		$error = $error . ERR_FORMAT . mysqli_real_escape_string($con, $_GET[GET_FORMAT]);
 	}
-	
-	
+
+
 	//If there has not been an error, procede
 	if (strlen($error) == 0){
 		echo(show_notifications($con, $target, $format));

+ 160 - 0
www/API/v1/sendlocation.php

@@ -0,0 +1,160 @@
+<?php
+
+	// $_GET valid parameters
+	define('GET_USER', 'user');
+	define('GET_PASS', 'pass');
+	define('GET_ACTION', 'action');
+	define('GET_LAT', 'lat');
+	define('GET_LON', 'lon');
+
+	// Valid values
+	define('ACTION_START', 'start');
+	define('ACTION_REFRESH', 'refresh');
+	define('ACTION_STOP', 'stop');
+	$actions = [ACTION_START, ACTION_REFRESH, ACTION_STOP];
+
+	// Error messages
+	define('ERR_USER', '-USER:');
+	define('ERR_ACTION', '-ACTION:');
+	define('ERR_LOCATION', '-TITLE:');
+
+	/****************************************************
+	* This function is called from almost everywhere at *
+	* the beggining of the page. It initializes the     *
+	* session variables, connect to the db, enabling    *
+	* the variable $con for futher use everywhere in    *
+	* the php code, and populates the arrays $user      *
+	* and $permission, with info about the user.        *
+	*                                                   *
+	* @return: (db connection): The connection handler. *
+	****************************************************/
+	function startdb(){
+		//Include the db configuration file. It's somehow like this
+		/*
+		 <?php
+		  $host = 'XXXX';
+		  $db_name = 'XXXX';
+		  $username_ro = 'XXXX';
+		  $username_rw = 'XXXX';
+		  $pass_ro = 'XXXX';
+		  $pass_rw = 'XXXX';
+		 ?>
+		*/
+		include('../../.htpasswd');
+
+		//Connect to to database
+		$con = mysqli_connect($host, $username_rw, $pass_rw, $db_name);
+
+		//Set encoding options
+		mysqli_set_charset($con, 'utf-8');
+		header('Content-Type: text/html; charset=utf8');
+		mysqli_query($con, 'SET NAMES utf8;');
+
+		//Return the db connection
+		return $con;
+	}
+
+	$con = startdb('rw');
+	$error = "";
+
+	//Get fields
+	$user = mysqli_real_escape_string($con, $_GET[GET_USER]);
+	$pass = mysqli_real_escape_string($con, $_GET[GET_PASS]);
+	$lat = mysqli_real_escape_string($con, $_GET[GET_LAT]);
+	$lon = mysqli_real_escape_string($con, $_GET[GET_LON]);
+	$action = mysqli_real_escape_string($con, $_GET[GET_ACTION]);
+
+	//Validate user
+	$q = mysqli_query($con, "SELECT id FROM user WHERE lower(username) = lower('$user') AND password = '$pass';");
+	if (mysqli_num_rows($q) == 0){
+		error_log(":SECURITY: Reporting location with wrong credentials (IP $_SERVER[REMOTE_ADDR])");
+		http_response_code(403); // Forbidden
+		$error = $error . ERR_USER . mysqli_real_escape_string($con, $_GET[GET_USER]);
+		error_log($error);
+		exit(-1);
+	}
+	// Get id
+	$r = mysqli_fetch_array($q);
+	$uid = $r['id'];
+
+	//Validate fields
+	if (!in_array($action, $actions)){
+		http_response_code(400); // Bad request
+		$error = $error . ERR_ACTION . $action;
+		error_log($error);
+        exit(-2);
+	}
+	if (is_numeric($lat) == false || is_numeric($lon) == false){
+		http_response_code(400); // Bad request
+		$error = $error . ERR_LOCATION . '($lat, $lon)';
+		error_log($error);
+        exit(-3);
+	}
+	if (strlen($lat) == 0 xor strlen($lon) == 0){
+		// Only one coordinate.
+		http_response_code(400); // Bad request
+		$error = $error . ERR_LOCATION . '($lat, $lon)';
+		error_log($error);
+        exit(-4);
+	}
+	if (strlen($lat) != 0 && ($lat < -90.0 || $lat > 90.0)){
+		// Invalid latitude
+		http_response_code(400); // Bad request
+		$error = $error . ERR_LOCATION . '(Lat: $lat)';
+		error_log($error);
+        exit(-5);
+	}
+	if (strlen($lon) != 0 && ($lon < -180.0 || $lon > 180.0)){
+		// Invalid longitude
+		http_response_code(400); // Bad request
+		$error = $error . ERR_LOCATION . '(Lon: $lat)';
+		error_log($error);
+        exit(-6);
+	}
+
+	// Discern action
+	switch ($action){
+		case ACTION_START:
+			// Insert
+			mysqli_query($con, "INSERT INTO location (lat, lon, action, user) VALUES ($lat, $lon, 'S', $uid);");
+			break;
+		case ACTION_REFRESH:
+			// Look for start node.
+			$q = mysqli_query($con, "SELECT id, start, action FROM location WHERE user = $uid AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
+			if (mysqli_num_rows($q) == 0){
+				// No recent reports. Start anew.
+				mysqli_query($con, "INSERT INTO location (lat, lon, action, user) VALUES ($lat, $lon, 'S', $uid);");
+			}
+			else{
+				$r = mysqli_fetch_array($q);
+				if ($r['action'] == 'F'){
+					// Previous track was stoped. Start anew.
+					mysqli_query($con, "INSERT INTO location (lat, lon, action, user) VALUES ($lat, $lon, 'S', $uid);");
+				}
+				else{
+					// Continue track.
+					$s = $r['id'];
+					mysqli_query($con, "INSERT INTO location (lat, lon, action, user, start) VALUES ($lat, $lon, 'R', $uid, $s);");
+				}
+			}
+			break;
+		case ACTION_STOP:
+			// Look for start node.
+			$q = mysqli_query($con, "SELECT id, start FROM location WHERE user = $uid AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
+			if (mysqli_num_rows($q) > 0){
+				$r = mysqli_fetch_array($q);
+				if ($r['action'] != 'F'){
+					// Finish track.
+					$s = $r['start'];
+					if (strlen($lat) > 0 && strlen($lon) > 0){
+						mysqli_query($con, "INSERT INTO location (lat, lon, action, user, start) VALUES ($lat, $lon, 'F', $uid, $s);");
+					}
+					else{
+						mysqli_query($con, "INSERT INTO location (action, user, start) VALUES ('F', $uid, $s);");
+					}
+				}
+			}
+			break;
+	}
+	http_response_code(204); // No content.
+?>

+ 168 - 0
www/API/v1/sendnotification.php

@@ -0,0 +1,168 @@
+<?php
+	//include("../functions.php");
+	//$con = startdb('rw');
+
+	// $_GET valid parameters
+	define('GET_USER', 'user');
+	define('GET_PASS', 'pass');
+	define('GET_TITLE_ES', 'title_es');
+	define('GET_TITLE_EN', 'title_en');
+	define('GET_TITLE_EU', 'title_eu');
+	define('GET_TEXT_ES', 'text_es');
+	define('GET_TEXT_EN', 'text_en');
+	define('GET_TEXT_EU', 'text_eu');
+	define('GET_DURATION', 'duration');
+	define('GET_ACTION', 'action');
+	define('GET_PERM', 'permalink');
+	define('GET_ID', 'id');
+	define('GET_GM', 'gm');
+
+	// Valid values
+	define('ACTION_TEXT', 'mensaje');
+	define('ACTION_BLOG', 'blog');
+	define('ACTION_ACTIVITIES', 'actividades');
+	define('ACTION_GALLERY', 'galeria');
+	define('ACTION_LOCALIZATION', 'localizacion');
+	define('ACTION_LABLANCA', 'lablanca');
+	define('ACTION_SCHEDULE', 'programa');
+	define('ACTION_GM_SCHEDULE', 'gprograma');
+	define('ACTION_US', 'nosotros');
+	$actions = [ACTION_TEXT, ACTION_BLOG, ACTION_ACTIVITIES, ACTION_GALLERY, ACTION_LOCALIZATION, ACTION_LABLANCA, ACTION_SCHEDULE, ACTION_GM_SCHEDULE, ACTION_US];
+
+	// Default values
+	define('DEF_GM', 0);
+	define('DEF_ACTION', ACTION_TEXT);
+
+	// Error messages
+	define('ERR_USER', '-USER:');
+	define('ERR_ACTION', '-ACTION:');
+	define('ERR_TITLE', '-TITLE:');
+	define('ERR_TEXT', '-TEXT:');
+	define('ERR_DURATION', '-DURATION:');
+	define('ERR_GM', '-GM:');
+	define('ERR_PERM', '-PERM:');
+	define('ERR_ID', '-ID:');
+
+	/****************************************************
+	* This function is called from almost everywhere at *
+	* the beggining of the page. It initializes the     *
+	* session variables, connect to the db, enabling    *
+	* the variable $con for futher use everywhere in    *
+	* the php code, and populates the arrays $user      *
+	* and $permission, with info about the user.        *
+	*                                                   *
+	* @return: (db connection): The connection handler. *
+	****************************************************/
+	function startdb(){
+		//Include the db configuration file. It's somehow like this
+		/*
+		 <?php
+		  $host = 'XXXX';
+		  $db_name = 'XXXX';
+		  $username_ro = 'XXXX';
+		  $username_rw = 'XXXX';
+		  $pass_ro = 'XXXX';
+		  $pass_rw = 'XXXX';
+		 ?>
+		*/
+		include('../../.htpasswd');
+
+		//Connect to to database
+		$con = mysqli_connect($host, $username_rw, $pass_rw, $db_name);
+
+		//Set encoding options
+		mysqli_set_charset($con, 'utf-8');
+		header('Content-Type: text/html; charset=utf8');
+		mysqli_query($con, 'SET NAMES utf8;');
+
+		//Return the db connection
+		return $con;
+	}
+
+	$con = startdb();
+
+	// Get fields
+	$user = mysqli_real_escape_string($con, $_GET[GET_USER]);
+	$pass = mysqli_real_escape_string($con, $_GET[GET_PASS]);
+	$title_es = urldecode(mysqli_real_escape_string($con, $_GET[GET_TITLE_ES]));
+	$title_en = urldecode(mysqli_real_escape_string($con, $_GET[GET_TITLE_EN]));
+	$title_eu = urldecode(mysqli_real_escape_string($con, $_GET[GET_TITLE_EU]));
+	$text_es = urldecode(mysqli_real_escape_string($con, $_GET[GET_TEXT_ES]));
+	$text_en = urldecode(mysqli_real_escape_string($con, $_GET[GET_TEXT_EN]));
+	$text_eu = urldecode(mysqli_real_escape_string($con, $_GET[GET_TEXT_EU]));
+	$duration = mysqli_real_escape_string($con, $_GET[GET_DURATION]);
+	$action = mysqli_real_escape_string($con, $_GET[GET_ACTION]);
+	$id = mysqli_real_escape_string($con, $_GET[GET_ID]);
+	$perm = mysqli_real_escape_string($con, $_GET[GET_PERM]);
+	$gm = mysqli_real_escape_string($con, $_GET[GET_GM]);
+
+	// Error control
+	$error = "";
+
+	// Validate user/pass
+	$q = mysqli_query($con, "SELECT id FROM user WHERE lower(username) = lower('$user') AND password = '$pass'");
+	if (mysqli_num_rows($q) == 0){
+		error_log(":SECURITY: Reporting location with wrong credentials (IP $_SERVER[REMOTE_ADDR])");
+		http_response_code(403); // Forbidden
+		$error = $error . ERR_USER . mysqli_real_escape_string($con, $_GET[GET_USER]);
+		error_log($error);
+		exit(-1);
+	}
+	$r = mysqli_fetch_array($q);
+	$uid = $r['id'];
+
+	//Validate fields
+	if (strlen($title_es) == 0){
+		http_response_code(400); // Bad request
+		$error = $error . ERR_TITLE . $title_es;
+		error_log($error);
+        exit(-2);
+	}
+
+	if (strlen($text_es) == 0){
+		http_response_code(400); // Bad request
+		$error = $error . ERR_TEXT . $text_es;
+		error_log($error);
+        exit(-3);
+	}
+
+	if (is_numeric($duration) == false || $duration < 1 && $duration > 48 * 60){
+		http_response_code(400); // Bad request
+		$error = $error . ERR_DURATION . $duration;
+		error_log($error);
+        exit(-4);
+	}
+
+	if (!in_array($action, $actions)){
+		http_response_code(400); // Bad request
+		$error = $error . ERR_ACTION . $action;
+		error_log($error);
+        exit(-5);
+	}
+
+	//Handle translations
+	if (strlen($title_en) == 0){
+		$title_en = $title_es;
+	}
+	if (strlen($title_eu) == 0){
+		$title_eu = $title_es;
+	}
+	if (strlen($text_en) == 0){
+		$text_en = $text_es;
+	}
+	if (strlen($text_eu) == 0){
+		$text_eu = $text_es;
+	}
+
+	//Insert
+	if (strlen($error) == 0){
+		error_log("INSERT INTO notification (user, title_es, title_en, title_eu, text_es, text_en, text_eu, action, duration) VALUES ($uid, '$title_es', '$title_en', '$title_eu', '$text_es', '$text_en', '$text_eu', '$action', $duration);");
+		mysqli_query($con, "INSERT INTO notification (user, title_es, title_en, title_eu, text_es, text_en, text_eu, action, duration) VALUES ($uid, '$title_es', '$title_en', '$title_eu', '$text_es', '$text_en', '$text_eu', '$action', $duration);");
+		http_response_code(204); // No content;
+		exit(0);
+	}
+	else{
+		error_log($error);
+		exit(-6);
+	}
+?>

+ 3 - 3
www/API/v1/sync.php

@@ -142,7 +142,7 @@
 				$tables = [ 'post', 'post_comment', 'post_image', 'post_tag' ];
 				break;
 			case SEC_ACTIVITIES:
-				$tables = [ 'activity', 'activity_itinerary', 'activity_comment', 'activity_image', 'activity_tag', 'activity_itinerary', 'location', 'album', 'photo', 'photo_album', 'photo_comment', 'place' ];
+				$tables = [ 'activity', 'activity_itinerary', 'activity_comment', 'activity_image', 'activity_tag', 'activity_itinerary', 'album', 'photo', 'photo_album', 'photo_comment', 'place' ];
 				break;
 			case SEC_GALLERY:
 				$tables = [ 'album', 'photo', 'photo_album', 'photo_comment', 'place' ];
@@ -151,7 +151,7 @@
 				$tables = [ 'festival', 'festival_day', 'festival_event', 'festival_event_image', 'festival_offer', 'place', 'people' ];
 				break;
 			case SEC_ALL:
-				$tables = [ 'activity', 'activity_itinerary', 'activity_comment', 'activity_image', 'activity_tag', 'album', 'photo', 'festival', 'festival_day', 'festival_event', 'festival_event_image', 'festival_offer', 'photo_album', 'place', 'post', 'post_comment', 'post_image', 'post_tag', 'settings', 'sponsor' ];
+				$tables = [ 'activity', 'activity_itinerary', 'activity_comment', 'activity_image', 'activity_tag', 'album', 'photo', 'festival', 'festival_day', 'festival_event', 'festival_event_image', 'festival_offer', 'photo_album', 'place', 'people', 'post', 'post_comment', 'post_image', 'post_tag', 'settings', 'sponsor' ];
 				break;
 			default:
 				//'Bad request' staus code
@@ -229,7 +229,7 @@
 			//Other cases: 
 			default:
 				//If the table is a public one and has not been listed above, all of its fields are public.
-				if (in_array($table, ['activity_image', 'activity_itinerary', 'activity_tag', 'festival', 'festival_day', 'festival_event', 'festival_event_image', 'festival_offer', 'photo_album', 'place', 'post_image', 'post_tag'])){
+				if (in_array($table, ['activity_image', 'activity_itinerary', 'activity_tag', 'festival', 'festival_day', 'festival_event', 'festival_event_image', 'festival_offer', 'photo_album', 'place', 'people', 'post_image', 'post_tag'])){
 					$q = mysqli_query($con, "SELECT * FROM $table;");
 				}
 				//If forbidden table

+ 5 - 5
www/actividades/actividad.php

@@ -159,7 +159,7 @@
 								if (mysqli_num_rows($q_it) > 0){
 									echo "<div id='activity_itinerary'><h3 class='entry_title'>Itinerario</h3>\n";
 									echo "<table id='activity_itinerary'>\n";
-									echo "<tr class='th'><th>$lng[activities_when]</th><th>$lng[activities_what]</th><th>$lng[activities_where]</th></tr>\n";
+									echo "<tr class='th'><th>$lng[activities_when]</th><th>$lng[activities_what]</th></tr>\n";
 									while ($r_it = mysqli_fetch_array($q_it)){
 										echo "<tr>\n";
 										echo "<div class='hidden' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'>\n";
@@ -176,14 +176,14 @@
 											echo "<td>$r_it[start] - $r_it[end]</td>";
 										}
 										else{
-											echo "<td>$r_it[start]</td>";
+											echo "<td class='time'>$r_it[start]</td>";
 										}
-										echo "<td><h5>$r_it[name]</h5><p class='description'>$r_it[description]</p></td>\n";
+										echo "<td><h5>$r_it[name]</h5><p class='description'>$r_it[description]</p><br/>\n";
 										if ($r_it['place_name'] == $r_it['place_address']){
-											echo "<td>$r_it[place_name]</td>\n";
+											echo "$r_it[place_name]</td>\n";
 										}
 										else{
-											echo "<td>$r_it[place_name]<span class='address'>($r_it[place_address])</span></td>\n";
+											echo "$r_it[place_name]<span class='address'>($r_it[place_address])</span></td>\n";
 										}
 										echo "</tr>\n";
 									}

+ 2 - 1
www/app/location.php

@@ -3,7 +3,8 @@
 	$con = startdb();
 		
 	//Get user entry
-	$q = mysqli_query($con, "SELECT lat, lon, dtime, username, manual, action FROM location, user WHERE action = 'report' AND user.id = location.user AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
+	// DEBUG 1=0. Disabled.
+	$q = mysqli_query($con, "SELECT lat, lon, dtime, username, manual, action FROM location, user WHERE 0=1 AND action = 'report' AND user.id = location.user AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
 	if (mysqli_num_rows($q) > 0){
 		$r = mysqli_fetch_array($q);
 		echo("<reporting>1</reporting>\n");

+ 2 - 1
www/app/notifications.php

@@ -3,7 +3,8 @@
 	$con = startdb();
 		
 	//Get user entry
-	$q = mysqli_query($con, "SELECT id, action, title_es, title_en, title_eu, text_es, text_en, text_eu FROM notification WHERE dtime > NOW() - INTERVAL duration MINUTE ORDER BY dtime DESC ;");
+	// 1=0 Old API is now disabled
+	$q = mysqli_query($con, "SELECT id, action, title_es, title_en, title_eu, text_es, text_en, text_eu FROM notification WHERE 1 = 0 AND dtime > NOW() - INTERVAL duration MINUTE ORDER BY dtime DESC ;");
 	while ($r = mysqli_fetch_array($q)){
 		echo("<notification>\n");
 		echo("\t<id>$r[id]</id>\n");

+ 10 - 0
www/css/actividades.css

@@ -113,6 +113,16 @@ div#activity_itinerary table#activity_itinerary td{
 	padding:	0.2em 0.5em 0.2em 0.5em;
 }
 
+div#activity_itinerary table#activity_itinerary td.time{
+	vertical-align: top;
+	border-right:	0.25em dotted #33333377;	
+	color:    #275573;
+  font-weight:  bold;
+  font-size:  1em;
+  margin:   1em 1em 0.3em 0em;
+}
+
+
 div#activity_itinerary table#activity_itinerary td h5{
 	margin:	0;
 }

+ 63 - 40
www/css/galeria.css

@@ -19,7 +19,6 @@ div.album_list{
 
 table.album_thumbnails td{
 	background-color:	#000000;
-/* 	display:			inline-block; */
 	width:				8em;
 	height:				8em;
 	text-align:			center;
@@ -121,10 +120,10 @@ div#screen_cover{
 div#photo_viewer{
 	position:			fixed;
 	display:			none;
-	top:				10%;
-	left:				10%;
-	right:				10%;
-	bottom:				10%;
+	top:					1em;
+	left:				4em;
+	right:				4em;
+	bottom:				1em;
 	opacity:			0;
 	transition:			all .6s ease-in-out;
 	z-index:			1001;
@@ -134,66 +133,86 @@ div#photo_viewer{
 
 /* /galeria/load_photo.php */
 
+div#photo_viewer div#viewer_container{
+	position:	absolute;
+	overflow-y:	auto;
+	top:			4.5em;
+	left:			0;
+	right:		0;
+	bottom:		1em;
+	margin:		-2em 0 0 0;
+	padding:	2em 0 0 0;
+}
+
+div#photo_viewer h3.section_title div#viewer_close_container{
+	height:			1.5em;
+	float:			right;
+	margin-top:		-0.3em;
+	margin-right:	-0.4em;
+}
+
+div#photo_viewer h3.section_title div#viewer_close_container img#viewer_close{
+	height:	100%;
+}
+
 div#photo_viewer div#viewer_table{
 	display:	table;
-	height:		100%;
 	width:		100%;
 }
 
 div#photo_viewer div#viewer_table div.viewer_row{
 	display:	table-row;
-	height:		100%;
 	width:		100%;
 }
 
 div#photo_viewer div#viewer_table div.viewer_row div.viewer_cell{
 	display:		table-cell;
-	max-height:		100%;
 	vertical-align:	top;
 }
 
 div#photo_viewer div#viewer_table div.viewer_row div#cell_image{
 	text-align:	center;
-	position:	fixed;
-	bottom:	10%;
-	top:	11%; /*Viewer is 10%*/
-	left:	11%;
-	right:	40%;
+	padding:	0 1em 0.5em 1em;
 	
 }
 
-div#photo_viewer div#viewer_table div.viewer_row div#cell_details{
+div#photo_viewer div#viewer_table div.viewer_row div#cell_image td.arrow{
+	width:	5%;
+}
+
+div#photo_viewer div#viewer_table div.viewer_row div#cell_image td#image{
+    width:  90%;
+}
+
+
+div#photo_viewer div#viewer_table div.viewer_row div#cell_comments{
 	width:		40%;
 }
 
 div#photo_viewer_image_container{
-	height:				85%;
 	width:				100%;
 	position:			relative;
 	display:			inline-block;
 	max-width:			100%;
 	overflow:			hidden;
-	background-color:	#000000;
 	text-align:			center;
 	vertical-align:		center;
 }
 
 img#photo_viewer_image{
-	border:			0.3em solid #112244;
+	border-radius:	0.5em;
+	border:     0.3em solid #112244;
 	box-shadow:		0 0 0.5em #112244;
- 	max-width:		90%;
+ 	max-width:		95%;
+	top:			10%;
 	bottom:			10%;
-	max-height:		80%; /*The viewer is 85%*/
+	max-height:		80%;
 }
 
 div#photo_viewer div#viewer_controls{
-	height:		10%;
 	width:		100%;
 	text-align:	center;
 	bottom:		10%;
-	left:		0;
-	right:		0;
-	position:	fixed;
 }
 
 div#photo_viewer div#viewer_controls img{
@@ -202,20 +221,32 @@ div#photo_viewer div#viewer_controls img{
 	transition:	all .3s ease-in-out;
 }
 
-div#photo_viewer div#viewer_controls img:hover{
-	-webkit-filter:	drop-shadow(0 0 0.3em #775599);
+div#photo_viewer img.viewer_arrow{
+	height:		3em;
+	width:		3em;
+	opacity:	0.4;
+}
+
+div#photo_viewer img.viewer_arrow:hover{
+    -webkit-filter:	drop-shadow(0 0 0.3em #775599);
     filter:			drop-shadow(0 0 0.3em #775599);
     -ms-filter:		"progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=0, Color='#759')";
     filter:			"progid:DXImageTransform.Microsoft.Dropshadow(OffX=0, OffY=0, Color='#759')";
+	opacity:		0.8;
 }
 
-div#photo_viewer_details{
-	position:	fixed;
-	top:		11%;
-	bottom:		11%;
-	right:		12%;
-	left:		60%;
-	overflow-y:	auto;
+
+div#photo_viewer img#viewer_arrow_left{
+	left:	0%;
+}
+
+div#photo_viewer img#viewer_arrow_right{
+    right:	0%;
+}
+
+div#photo_data{
+	position:	relative;
+	height:		100%;
 }
 
 div#photo_data h4{
@@ -244,12 +275,6 @@ div#photo_data span#photo_user{
 	font-style:	italic;
 }
 
-
-div#photo_viewer_comments{
-	height:		100%;
-	overflow:	auto;
-}
-
 div.photo_viewer_comment{
 	border:		0.1em solid rgba(50, 50, 50, 0.2);
 	margin:		0;
@@ -303,8 +328,6 @@ div.form_photo{
 	text-align:		center;
 	margin:			1.5em;
 	padding:		1em;
-/* 	border:			0.1em solid #000010; */
-/* 	border-radius:	0.5em; */
 }
 
 div.form_photo img{

+ 72 - 15
www/css/index.css

@@ -1,5 +1,7 @@
+/* Location section */
+
 /* Festival section */
-table.festival_section_table{
+/*div#festivals{
 	width:	100%;
 }
 
@@ -20,37 +22,92 @@ table.festival_section_table tr td div.entry{
 }
 
 table.festival_section_table tr td div#festivals_summary{
-/* 	min-height:		15em; */
+ 	min-height:		15em;
 }
 
-table.festival_section_table tr td div#festivals_summary img{
+table.festival_section_table tr td div#festivals_summary img{*/
+div#festivals div#festivals_summary img{
 	display:		inline-block;
 	max-width:		40%;
 	max-height:		15em;
 	vertical-align:	top;
-	float:			left;
+	wfloat:			left;
 	margin-right:	2em;
+	border: 0.1em solid black;
+	margin:	0.5em;
 }
 
-table.festival_section_table tr td div#festival_entry_map{
-	text-align:	center;
+div#festivals span#festivals_summary_text{
+	display:	inline-block;
+}
+
+div#festivals div#festivals_schedule_table{
+	display:	table;
+	width:		100%;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row{
+	display:	table-row;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell{
+	display:	table-cell;
+	width:		50%;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div#festivals_gm{
+	margin: 0.4em 0.2em 0.4em 0.4em;
 }
 
-div.festival_event{
-	margin-left:	1.5em;
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div#festivals_city{
+	margin: 0.4em 0.4em 0.4em 0.2em;
 }
 
-table.festival_section_table tr td div#festival_entry_map h3{
-	text-align:	left;
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event{
+	margin:			1em;
+	padding:		0.3em 0.3em 0.3em 0.5em;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event h4{
+	margin:			1em 0.2em 0.2em 0em;
+	font-weight:	bold;
+	color:			#444444;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event div.schedule_content{
+	border-left:	0.1em dotted black;
+	margin-left:	0.5em;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event span.title{
+	font-weight:	bold;
+	font-size:		120%;
+	color:			#275573;
+	margin:			1em 0.5em 0.7em 0.2em;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event p.description{
+	margin:	0.2em 1em 1em 1em;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event table.location{
+	margin:		0.3em 1em 0.3em 1.6em;
+	font-size:	90%;
+	color:		#222222;
+}
+
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event table.location img{
+	max-width:	1.3em;
+	max-hieght:	1.5em;
 }
 
-table.festival_section_table tr td div#festival_entry_map iframe{
-	width:		80%;
-	margin:		auto;
-	min-height:	15em;
-	max-height:	20em;
+div#festivals div#festivals_schedule_table div#festivals_schedule_row div.festivals_schedule_cell div.festival_event table.location span.address{
+	font-size:	80%;
+	font-style:	italic;
+	color:		#444444;
 }
 
+
 table.festival_section_table tr td div.festival_schedule span.title{
 	font-weight:	bold;
 /* 	font-size:		105%; */

+ 57 - 19
www/css/lablanca.css

@@ -46,7 +46,32 @@ div.horiz p{
 	vertical-align:	top;
 }
 
+div#past_festivals ul li{
+	margin:	0.5em;
+}
+
+
 /* fiestas.php */
+div#festivals_image_top_container{
+	display:	block;
+	text-align:	center;
+	margin:		0.5em auto 0.5em auto;
+}
+
+div#festivals_image_top_container div#festivals_image_container{
+	display:		inline-block;
+	border:			0.1em solid #001133;
+	border-radius:	1em;
+	box-shadow:		0 0 1em #111122;
+	margin:			0.8em auto 0.8em auto;
+}
+
+div#festivals_image_top_container div#festivals_image_container img#festivals_image{
+	border-radius:	1em;
+	max-width:		60em;
+	max-height:		20em;
+}
+
 div#schedule{
 	display:		inline-block;
 	vertical-align:	top;
@@ -74,7 +99,7 @@ table.schedule td{
 	vertical-align:	top;
 	padding-left:	0.5em;
 	padding-right:	0.5em;
-	padding-bottom:	0.6em;
+	padding-bottom:	1em;
 }
 
 table.schedule td span.time{
@@ -83,49 +108,47 @@ table.schedule td span.time{
 
 table.schedule td span.title{
 	font-weight:	bold;
+	font-style:		italic;
+	font-size:		110%;
+	color:			#001133;
+	margin:			0 0.5em 0.5em 0.3em;
+	letter-spacing:	0.05em;
 }
 
-table.schedule td span.description{
-	font-size:		90%;
-	font-style:		italic;
-	margin-left:	1.2em;
+table.schedule td div.description{
+	margin:	0.3em 2em 0.5em 1.2em;
+	color:	#222222;
 }
 
 table.schedule td.timeline{
 	width:				0.06em;
-	padding:			0;
-	background-color:	#000000;
+	padding:			0 0 1em 0;
+	border-left:		dotted #333333 0.1em;
 	padding-left:		0;
 	padding-right:		0;
 	
 }
 
-
-
 table.schedule td.timeline img.timeline_dot{
 	width:			1em;
 	height:			1em;
-	margin-left:	-0.44em;
-	margin-right:	-0.44em;
-	margin-top:		0.3em;
+	margin-left:	-0.47em;
+	margin-right:	-0.41em;
+	margin-top:		0.2em;
 }
 
-table.schedule table.location{
+table.schedule div.location{
 	font-size:			80%;
 	border-collapse:	collapse;
 	margin-left:		2em;
 }
 
-table.schedule table.location td{
-	padding:	0.2em;
-}
-
-table.schedule table.location img{
+table.schedule div.location img{
 	max-height:		1.3em;
 	vertical-align:	middle;
 }
 
-table.schedule table.location span.address{
+table.schedule div.location span.address{
 	font-style:	italic;
 }
 
@@ -163,6 +186,12 @@ div#prices table#table_days td{
 	padding:	0.5em 2em 0.5em 2em; 
 }
 
+div#prices table#table_days td.price{
+	color:			#001133;
+	font-weight:	bold;
+	font-size:		110%;
+}
+
 div#prices td.price{
 	min-width:	4em;
 	text-align:	right;
@@ -178,10 +207,19 @@ div#prices table#table_offers td{
 	border-top:	0.2em solid #aaaaaa;
 }
 
+div#prices table#table_offers td.price{
+	min-width:		4em;
+	text-align:		right;
+	color:			#001133;
+	font-weight:	bold;
+	font-size:		110%;
+}
+
 div#prices table#table_offers p.description{
 	margin:		0.2em 0.2em 0.5em 2em;
 	font-size:	90%;
 	font-style:	italic;
+	color:		#444444;
 }
 
 

+ 8 - 2
www/css/m/galeria.css

@@ -23,7 +23,7 @@ div#photo_viewer div#viewer_table div.viewer_row div#cell_image{
 	text-align:	center;
 	position:	initial;
 	bottom:		initial;
-	top:		initial; /*Viewer is 10%*/
+	top:		initial;
 	left:		initial;
 	right:		initial;
 	height:		50%;
@@ -38,10 +38,11 @@ div#photo_viewer div#viewer_table div.viewer_row div#cell_details{
 
 div#photo_viewer_image_container{
 	height:				100%;
+	padding-top:	0;
 }
 
 img#photo_viewer_image{
-	max-height:		95%; /*The viewer is 85%*/
+	max-height:		95%;
 }
 
 div#photo_viewer div#viewer_controls{
@@ -70,3 +71,8 @@ div#file_box span#select_mobile{
 	font-weight:	bold;
 	font-size:		130%;
 }
+
+div#cell_comments{
+	width:	initial !important;
+	margin: 0 1em 0.5em 1em;
+}

+ 7 - 1
www/css/m/lablanca.css

@@ -22,6 +22,12 @@ div#content_table div.content_tr div#content_td_prices{
 	width:		100%;
 }
 
+div#festivals_image_top_container div#festivals_image_container img#festivals_image{
+	border-radius:	0.5em;
+	max-width:		initial;
+	max-height:		15em;
+}
+
 div#schedule{
 	display:		block;
 	margin-right:	0em;
@@ -29,4 +35,4 @@ div#schedule{
 
 div#prices{
 	display:		block;
-}
+}

+ 14 - 0
www/css/m/traducir.css

@@ -0,0 +1,14 @@
+div.translation{
+	display:		block;
+	width:			100%;
+}
+
+div#translation input,textarea{
+	width:			90%;
+}
+
+table#buttons td input{
+	height:	3.5em;
+	width:	100%;
+}
+

+ 94 - 0
www/css/traducir.css

@@ -0,0 +1,94 @@
+div.translation{
+	display:		inline-block;
+	margin:			0;
+	padding:		1em 1em 2em 1em;
+	width:			45%;
+	vertical-align:	top;
+}
+
+div.translation h3{
+	margin-bottom:	2em;
+}
+
+div#original span, p{
+	color:		#333333;
+	font-style:	italic;
+	margin:		1em;
+}
+
+div#translation input, textarea{
+	margin:		1em;
+	width:		100%;
+}
+
+table#buttons{
+	width:	100%;
+}
+
+table#buttons td{
+	padding:	0.3em;
+	width:		33%;
+}
+
+table#buttons td input{
+	height:	2.5em;
+	width:	100%;
+}
+
+table#buttons td input#next{
+	border:				0.2em solid #ff5555;
+	background-color:	#671212;
+}
+
+table#buttons td input#save{
+	border:				0.2em solid #00ff78;
+	background-color:	#126745;
+}
+
+div#w_error{
+	position:	fixed;
+	top:		20%;
+	bottom:		20%;
+	left:		10%;
+	right:		10%;
+	display:	none;
+	text-align:	center;
+	height:		60%;
+	opacity:	0;
+	-webkit-transition: opacity 0.5s ease-in-out;
+    -moz-transition: opacity 0.5s ease-in-out;
+    transition: opacity 0.5s ease-in-out;
+}
+
+div#w_error div.entry{
+	height:	80%;
+}
+
+div#w_error div.entry table{
+	height:	80%;
+	width:	100%;
+	margin:	auto;
+}
+
+div#w_error input{
+	height:		4em;
+}
+
+/* Initial page */
+
+div#w_init div.entry{
+	text-align:	center;
+}
+div#w_init div.entry a.lang{
+	display:		inline-block;
+	width:			30%;
+	border-radius:      0.3em;
+    border:             0.2em solid #0078ff;
+    font-weight:        bold;
+    color:              #ffffff;
+    background-color:   #124567;
+    cursor:             pointer;
+    margin:             1em;
+	padding:			1em;
+    letter-spacing:     0.1em;
+}

+ 61 - 3
www/functions.php

@@ -435,10 +435,25 @@
 		$bot_kw[20] = 'commerce';
 		$bot_kw[21] = 'html';
 		$bot_kw[22] = 'fetch';
-		
+		$bot_kw[23] = 'google';
+		$bot_kw[24] = 'facebook';
+		$bot_kw[25] = 'whatsapp';
+		$bot_kw[26] = 'pinterest';
+		$bot_kw[27] = 'scrapy';
+		$bot_kw[28] = 'libwww';
+		$bot_kw[29] = 'java standard library';
+		$bot_kw[30] = 'default browser';
+		$bot_kw[31] = 'twingly recon';
+		$bot_kw[32] = 'siteexplorer';
+		$bot_kw[33] = 'yandex';
+		$bot_kw[34] = 'wotbox';
+		$bot_kw[35] = 'apache synapse';
+		$bot_kw[36] = 'catexplorador';
+		$bot_kw[37] = 'internet archive';
+
 		$i = 0;
 		while ($i < sizeof($bot_kw)) {
-			if (strpos(strtolower($uagent), $bot_kw[$i]) !== false){
+			if (strpos(strtolower($uagent), $bot_kw[$i]) !== false || strpos(strtolower($browser), $bot_kw[$i]) !== false){
 				mysqli_close($con);
 				return;
 			}
@@ -462,10 +477,53 @@
 		}
 		
 		if (is_array($ad_static)){
-			foreach ($ad_static as &$sponsor) {
+			foreach ($ad_static as $sponsor) {
 				mysqli_query($con, "UPDATE sponsor SET print_static = print_static + 1 WHERE id = $sponsor;");
 			}
 		}
 	}
+
+	function recalculateStats($day = null){
+		$con = startdb('rw');
+
+		// Visit count
+		$s = "SELECT date(dtime) AS day, count(stat_visit.id) AS visit FROM stat_view, stat_visit where stat_visit.id = stat_view.visit";
+		if (day != null){
+			$s = $s . " AND date(dtime) = str_to_date('$day', '%Y-%m-%d')";
+		}
+		$s = $s . " GROUP BY date(dtime);";
+		$q = mysqli_query($con, $s);
+		while ($r = mysqli_fetch-array($q)){
+			$q_check = mysqli_query("SELECT date FROM stat_daily_visit WHERE day = str_to_date('$day', '%Y-%m-%d')");
+			if (mysqli_num_rows($q_check) > 0){
+				// Update
+				mysqli_query($con, "UPDATE stat_daily_visit SET visit = $r[visit] WHERE day = str_to_date('$day', '%Y-%m-%d')");
+			}
+			else{
+				// Insert
+				mysqli_query($con, "INSERT INTO stat_daily_visit (day, visit) VALUES (str_to_date('$day', '%Y-%m-%d'), $r[visit])");
+			}
+		}
+
+		// Visit count by os and browser.
+		$s = "SELECT date(dtime) AS day, os, browser, count(stat_visit.id) AS visit FROM stat_view, stat_visit where stat_visit.id = stat_view.visit";
+		if (day != null){
+			$s = $s . " AND date(dtime) = str_to_date('$day', '%Y-%m-%d')";
+		}
+		$s = $s . " GROUP BY date(dtime), os, browser;";
+		$q = mysqli_query($con, $s);
+		while ($r = mysqli_fetch-array($q)){
+			$q_check = mysqli_query("SELECT date FROM stat_daily_visit_browser WHERE day = str_to_date('$day', '%Y-%m-%d') AND os = $r[os] AND browser = $r[browser]");
+			if (mysqli_num_rows($q_check) > 0){
+				// Update
+				mysqli_query($con, "UPDATE stat_daily_visit_browser SET visit = $r[visit] WHERE day = str_to_date('$day', '%Y-%m-%d') AND os = $r[os] AND browser = $r[browser]");
+			}
+			else{
+				// Insert
+				mysqli_query($con, "INSERT INTO stat_daily_visit_browser (day, os, browser, visit) VALUES (str_to_date('$day', '%Y-%m-%d'), $r[os], $[browser], $r[visit])");
+			}
+		}
+		
+	}
 ?>
 	

+ 16 - 14
www/galeria/album.php

@@ -4,6 +4,7 @@
 	include("../functions.php");
 	$con = startdb();
 	$proto = getProtocol();
+	#server = "$proto$http_host";
 	
 	//Language
 	$lang = selectLanguage();
@@ -32,15 +33,15 @@
 		<link rel="shortcut icon" href="<?php echo "$proto$http_host/img/logo/favicon.ico";?>">
 		<!-- CSS files -->
 		<style>
-			<?php 
-				include("../css/ui.css"); 
+			<?php
+				include("../css/ui.css");
 				include("../css/galeria.css");
 			?>
 		</style>
 		<!-- CSS for mobile version -->
 		<style media="(max-width : 990px)">
-			<?php 
-				include("../css/m/ui.css"); 
+			<?php
+				include("../css/m/ui.css");
 				include("../css/m/galeria.css");
 			?>
 		</style>
@@ -59,7 +60,7 @@
 		<meta property="og:title" content="<?php echo $l['title'];?> - Gasteizko Margolariak"/>
 		<meta property="og:url" content="<?php echo "$proto$http_host/galeria/$perm"; ?>"/>
 		<meta property="og:description" content="<?php echo strip_tags($r['description']); ?>"/>
-		<meta property="og:image" content="<?php  echo "$proto$http_host/img/logo/logo.png";?>"/> 
+		<meta property="og:image" content="<?php  echo "$proto$http_host/img/logo/logo.png";?>"/>
 		<meta property="og:site_name" content="Gasteizko Margolariak"/>
 		<meta property="og:type" content="website"/>
 		<meta property="og:locale" content="<?php echo $lang; ?>"/>
@@ -74,14 +75,15 @@
 		<?php include("../header.php"); ?>
 		<div id="content">
 			<div class="section" id="album" itemscope itemtype='https://schema.org/ImageGallery'>
-				<div class='hidden' itemprop='author creator' itemscope itemtype='http://schema.org/Organization'>\n");
-					<meta itemprop='legalName' content='Asociaci&oacute;n Cultural Recreativa Gasteizko Margolariak'/>\n");
-					<meta itemprop='name' content='Gasteizko Margolariak'/>\n");
-					<meta itemprop='logo' content='$proto$http_host/img/logo/logo.png'/>\n");
-					<meta itemprop='foundingDate' content='03-02-2013'/>\n");
-					<meta itemprop='telephone' content='+34637140371'/>\n");
-					<meta itemprop='url' content='<?php echo("$proto$http_host"); ?>'/>\n");
-				</div>\n");
+				<div class='hidden' itemprop='author creator' itemscope itemtype='http://schema.org/Organization'>
+					<meta itemprop='legalName' content='Asociaci&oacute;n Cultural Recreativa Gasteizko Margolariak'/>
+					<meta itemprop='name' content='Gasteizko Margolariak'/>
+					<meta itemprop='logo' content='$proto$http_host/img/logo/logo.png'/>
+					<meta itemprop='foundingDate' content='03-02-2013'/>
+					<meta itemprop='telephone' content='+34637140371'/>
+					<meta itemprop='url' content='<?=$server ?>'/>
+				</div>
+
 				<?php
 					//Header
 					echo("<h3 class='section_title' itemprop='name' id='album_title'>$r[title]</h3>\n");
@@ -90,7 +92,7 @@
 						echo $r['description'];
 						echo "</div>\n";
 					}
-				
+
 					//Photos of the album
 					$q_photo = mysqli_query($con, "SELECT id, file, permalink, title_$lang AS title, description_$lang AS description, photo.dtime AS dtime, uploaded, width, height, size, user, username FROM photo, photo_album WHERE photo_album.photo = id AND album = $r[id] ORDER BY photo.dtime DESC;");
 					/* TODO AND approved = 1*/

+ 107 - 65
www/galeria/load_photo.php

@@ -3,6 +3,8 @@
 	include("../functions.php");
 	$con = startdb();
 	$proto = getProtocol();
+	$server = "$proto$http_host";
+
 	
 	//Language
 	$lang = selectLanguage();
@@ -16,72 +18,112 @@
 	}
 	else{
 		$r = mysqli_fetch_array($q);
-		echo "<div id='viewer_table'><div class='viewer_row'><div class='viewer_cell' id='cell_image'>\n";
-		echo "<img id='photo_viewer_image' src='/img/galeria/preview/$r[file]'/>\n";
-		echo "</br>\n";
-		//Arrows
-		echo "<div id='viewer_controls'>\n";
-		echo "<img id='viewer_arrow_left' class='pointer' alt=' ' src='$proto$http_host/img/misc/slid-left.png' onClick='scrollPhoto(-1);'/>\n";
-		echo "<img id='viewer_arrow_right' class='pointer' alt=' ' src='$proto$http_host/img/misc/slid-right.png' onClick='scrollPhoto(1);'/>\n";
-		echo "<img id='viewer_close' class='pointer mobile' alt=' ' src='$proto$http_host/img/misc/close.png' onClick='closeViewer();'/>\n";
-		echo "</div>\n"; //viewer_controls
-		echo "</div>\n"; //cell
-		echo "<div class='viewer_cell' id='cell_details'>\n";
-		echo "<div id='photo_viewer_details'>\n";
-		echo "<div class='entry' id='photo_data'>\n";
-		if (strlen($r['title']) > 0){
-			echo "<h3 class='entry_title'>$r[title]</h3>\n";
-		}
-		if (strlen($r['description']) > 0){
-			echo "<span id='photo_description'>$r[description]</span>\n";
-		}
-		echo "<span id='photo_date'>" . formatDate($r['uploaded'], $lang) . "</span>\n";
-		if (strlen($r['username']) > 0){
-			echo "<span id='photo_user'>$lng[gallery_user]$r[username]</span>\n";
-		}
-		echo "</div>\n";
-		$q_comment = mysqli_query($con, "SELECT * FROM photo_comment WHERE photo = $r[id];");
-		$comment_count = mysqli_num_rows($q_comment);
-		echo "<div class='entry' id='comments_section'/>\n";
-		echo "<div id='photo_viewer_comment_counter'>\n";
-		switch ($comment_count){
-			case 0:
-				echo "<h3 class='entry_title'><meta itemprop='interactionCount' content='0'/>$lng[gallery_comment_count_0]</h3>\n";
-				break;
-			case 1:
-				echo "<h3 class='entry_title'><span itemprop='interactionCount'>1</span> $lng[gallery_comment_count_1]</h3>\n";
-				break;
-			default:
-				echo "<h3 class='entry_title'><span itemprop='interactionCount'>$comment_count</span> $lng[gallery_comment_count_several]</h3>\n";
-		}
-		echo "</div>\n";
-		echo "<div id='comment_list'>\n";
-		//WARNING: If changes are done here, do the same in comment.php
-		while ($r_comment = mysqli_fetch_array($q_comment)){
-			echo "<div itemprop='comment' itemscope itemtype='http://schema.org/UserComments' id='comment_$r_comment[id]' class='comment'>\n";
-			//When official users are implementes, see if there is user or username
-			echo "<span itemprop='creator' class='comment_user'>$r_comment[username]</span>\n";
-			echo "<span class='comment_date date'><meta itemprop='commentTime' content='$r_comment[isodate]'/>" . formatDate($r_comment['dtime'], $lang) . "</span>\n";
-			echo "<p itemprop='commentText' class='comment_text'>$r_comment[text]</p>";
-			echo "<hr class='comment_line'/>\n";
-			echo "</div>\n";
-		}
-		echo "</div>\n";
-		#Comment form
-		echo "<div class='comment' id='comment_new'>\n";
-		echo "<form id='comment_form' method='post' action='/' onsubmit='event.preventDefault();postComment($r[id], \"$lang\");'>\n";
-		echo "<textarea id='new_comment_text' name='text' maxlength='1800' onChange='defaultInputBorder(this);' onKeyDown='defaultInputBorder(this);' placeholder='$lng[blog_placeholder_text]'></textarea>\n";
-		//echo "<input type='hidden' name='id' value='$id'>\n";
-		echo "<div id='identification_form'>\n";
-		echo "<br><input id='new_comment_user' name='user' maxlength='50' type='text' placeholder='$lng[blog_placeholder_name]' onChange='defaultInputBorder(this);' onKeyDown='defaultInputBorder(this);'/>\n";
-		echo "<input type='submit' value='$lng[blog_send]'/>\n";
-		echo "</div>\n";
-		echo "</form>\n";
-		echo "</div>\n"; //New comment
-		echo "</div>\n"; //Comments
-		echo "</div>\n"; //Cell
+
+		// Get album name
+		$q_album = mysqli_query($con, "SELECT album.title_$lang AS title FROM album, photo_album WHERE album = album.id AND photo = $r[id]");
+		$r_album = mysqli_fetch_array($q_album);
+?>
+		<h3 class='section_title'>
+<?php
+			if (strlen($r['title']) > 0){
+				echo($r['title']);
+			}
+			else{
+				echo($r_album['title']);
+			}
+?>
+			<div id='viewer_close_container'>
+				<img id='viewer_close' class='pointer' alt=' ' src='<?=$server?>/img/misc/close.png' onClick='closeViewer();'/>
+			</div>
+		</h3>
+		<div id='viewer_container'>
+			<div id='viewer_table'>
+				<div class='viewer_row'>
+					<div class='viewer_cell' id='cell_image'>
+						<div class='entry' id='photo_data'>
+							<table>
+								<tr>
+									<td class='arrow'>
+										<img id='viewer_arrow_left' class='viewer_arrow pointer' alt=' ' src='<?=$server?>/img/misc/slid-left.png' onClick='scrollPhoto(-1);'/>
+									</td>
+									<td id='image'>
+										<div id='photo_viewer_image_container'>
+											<img id='photo_viewer_image' src='/img/galeria/preview/<?=$r['file']?>'/>
+										</div>
+									</td>
+									<td class='arrow'>
+										<img id='viewer_arrow_right' class='viewer_arrow pointer' alt=' ' src='<?=$server?>/img/misc/slid-right.png' onClick='scrollPhoto(1);'/>
+									</td>
+								</tr>
+							</table>
+							<!-- Arrows -->
+							<!--<div id='viewer_controls'>
+								<img id='viewer_arrow_left' class='viewer_arrow pointer' alt=' ' src='<?=$server?>/img/misc/slid-left.png' onClick='scrollPhoto(-1);'/>
+								<img id='viewer_arrow_right' class='viewer_arrow pointer' alt=' ' src='<?=$server?>/img/misc/slid-right.png' onClick='scrollPhoto(1);'/>
+							</div>  #viewer_controls -->
+<?php
+							if (strlen($r['description']) > 0){
+								echo("<span id='photo_description'>$r[description]</span>\n");
+							}
+							echo("<span id='photo_date'>" . formatDate($r['uploaded'], $lang) . "</span>\n");
+							if (strlen($r['username']) > 0){
+								echo("<span id='photo_user'>$lng[gallery_user]$r[username]</span>\n");
+							}
+?>
+						</div> <!-- #photo_data -->
+					</div>  <!-- #cell_image -->
+					<div class='viewer_cell' id='cell_comments'>
+						<div id='photo_viewer_details'>
+<?php
+							$q_comment = mysqli_query($con, "SELECT * FROM photo_comment WHERE photo = $r[id];");
+							$comment_count = mysqli_num_rows($q_comment);
+?>
+							<div class='entry' id='comments_section'/>
+								<div id='photo_viewer_comment_counter'>
+<?php
+									switch ($comment_count){
+										case 0:
+											echo("<h3 class='entry_title'><meta itemprop='interactionCount' content='0'/>$lng[gallery_comment_count_0]</h3>\n");
+											break;
+										case 1:
+											echo("<h3 class='entry_title'><span itemprop='interactionCount'>1</span> $lng[gallery_comment_count_1]</h3>\n");
+											break;
+										default:
+											echo("<h3 class='entry_title'><span itemprop='interactionCount'>$comment_count</span> $lng[gallery_comment_count_several]</h3>\n");
+									}
+?>
+								</div> <!-- #photo_viewer_comment_counter -->
+								<div id='comment_list'>
+<?php
+									//WARNING: If changes are done here, do the same in comment.php
+									while ($r_comment = mysqli_fetch_array($q_comment)){
+?>
+										<div itemprop='comment' itemscope itemtype='http://schema.org/UserComments' id='comment_<?=$r_comment['id']?>' class='comment'>
+											<span itemprop='creator' class='comment_user'><?=$r_comment['username']?></span>
+											<span class='comment_date date'><meta itemprop='commentTime' content='<?=$r_comment['isodate']?>'/><?=formatDate($r_comment['dtime'], $lang)?></span>
+											<p itemprop='commentText' class='comment_text'><?=$r_comment['text']?></p>
+											<hr class='comment_line'/>
+										</div>
+<?php
+									}
+?>
+								</div> <!-- #comment_list -->
+								<!-- Comment form -->
+								<div class='comment' id='comment_new'>
+									<form id='comment_form' method='post' action='/' onsubmit='event.preventDefault();postComment(<?=$r['id']?>, "<?=$lang?>");'>
+										<textarea id='new_comment_text' name='text' maxlength='1800' onChange='defaultInputBorder(this);' onKeyDown='defaultInputBorder(this);' placeholder='<?=$lng[blog_placeholder_text]?>'></textarea>
+										<div id='identification_form'>
+											<br/>
+											<input id='new_comment_user' name='user' maxlength='50' type='text' placeholder='<?=$lng['blog_placeholder_name']?>' onChange='defaultInputBorder(this);' onKeyDown='defaultInputBorder(this);'/>
+											<input type='submit' value='<?=$lng['blog_send']?>'/>
+										</div> <!-- #identification_form -->
+									</form>
+								</div> <!-- #comment_new -->
+							</div> <!-- #comments_section -->
+						<!-- </div>  #cell_details -->
+<?php
 		echo "</div>\n"; //Row
-		echo "</div>\n"; //Table
+		echo "</div></div>\n"; //Container
 		
 		stats(-1, 0, "photo", "$r[id]");
 	}

+ 299 - 188
www/index.php

@@ -23,21 +23,21 @@
 		<link rel="shortcut icon" href="<?php echo "$proto$http_host/img/logo/favicon.ico";?>">
 		<!-- CSS files -->
 		<style>
-			<?php 
+<?php 
 				include("css/ui.css"); 
 				include("css/index.css");
-			?>
+?>
 		</style>
 		<!-- CSS for mobile version -->
 		<style media="(max-width : 990px)">
-			<?php 
+<?php 
 				include("css/m/ui.css"); 
 				include("css/m/index.css");
-			?>
+?>
 		</style>
 		<!-- Script files -->
 		<script type="text/javascript">
-			<?php include("script/ui.js"); ?>
+<?php include("script/ui.js"); ?>
 		</script>
 		<!-- Meta tags -->
 		<link rel="canonical" href="<?php echo "$proto$http_host"; ?>"/>
@@ -59,188 +59,299 @@
 		<meta name="robots" content="index follow"/>
 	</head>
 	<body>
-		<?php include("header.php"); ?>
+<?php include("header.php"); ?>
 		<div id="content">
-			<?php
+
+<?php		
+				//Location section
+				$q_location = mysqli_query($con, "SELECT lat, lon FROM location WHERE action = 'report' AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
+				if (mysqli_num_rows($q_location) > 0){
+					$r_location = mysqli_fetch_array($q_location);
+?>
+					<div class='section' id='location'>
+					<h3 class='section_title'><?=$lng[index_festivals_location]?></h3>
+						<div class='entry' id='map'>
+							<iframe src='https://www.google.com/maps/embed/v1/place?key=AIzaSyCZHP7t2on_G3eyyoCTfhGAlDx1mJnX7iI&q=<?=$r_location[lat]?>,<?=$r_location[lon]?>' allowfullscreen></iframe>
+						</div>
+					</div>
+<?php
+				}
+
 				//Festivals section
 				$year = date("Y");
 				$q_settings = mysqli_query($con, "SELECT value FROM settings WHERE name = 'festivals';");
 				$r_settings = mysqli_fetch_array($q_settings);
 				$festivals = $r_settings['value'];
 				if ($festivals == 1){
-					echo "<div class='section' id='festivales' itemscope itemtype='$protoschema.org/Event'>\n";
-					echo "<meta itemprop='inLanguage' content='$lang'/>\n";
-					echo "<meta itemprop='name' content='$lng[index_festivals_header] $year'/>\n";
-					echo "<meta itemprop='description' content='$lng[index_festivals_header] $year'/>\n";
-					echo "<meta itemprop='startDate' content='$year-08-04'/>\n";
-					echo "<meta itemprop='endDate' content='$year-08-09'/>\n";
-					echo "<meta itemprop='url' content='$proto$http_host/lablanca/'/>\n";
-					echo("<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'><meta itemprop='address' itemprop='name' content='Vitoria-Gasteiz'/></span>\n");
-					echo "<h3 class='section_title'>$lng[index_festivals_header] $year</h3>\n";
-					echo "<table class='festival_section_table'><tr>\n";
-					
-					//Summary
-					$q_festivals = mysqli_query($con, "SELECT text_$lang AS text, summary_$lang AS summary, img FROM festival WHERE year = $year;");
-					if(mysqli_num_rows($q_festivals)){
-						echo "<td><div class='entry' id='festivals_summary'>\n";
-						$r_festivals = mysqli_fetch_array($q_festivals);
-						if ($r_festivals['img'] != ''){
-							echo "<meta itemprop='image' content='$proto$http_host/img/fiestas/$r_festivals[img]'/>\n";
-							echo "<img id='festivals_image' alt=' ' src='$proto$http_host/img/fiestas/$r_festivals[img]'/>\n";
-						}
-						if ($r_festivals['summary'] != ''){
-							echo "<span class='entry_title' id='festivals_summary_text'><br/>$r_festivals[summary]</span>\n";
-							echo "<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='$proto$http_host/lablanca/'>$lng[index_festivals_link]</a>\n";
-						}
-						else{
-							echo "<span id='festivals_summary_text'><br/>" . cutText($r_festivals['text'], 300, "$lng[index_read_more]", "$proto$http_host/lablanca/") . "</span>\n";
-							//echo "<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='$proto$http_host/lablanca/'>$lng[index_festivals_link]</a>\n";
-						}
-						echo "</div></td>\n";
-					}
-					
-					
-					//Location
-					$q_location = mysqli_query($con, "SELECT lat, lon FROM location WHERE action = 'report' AND dtime > NOW() - INTERVAL 30 MINUTE ORDER BY dtime DESC LIMIT 1;");
-					if (mysqli_num_rows($q_location) > 0){
-						$r_location = mysqli_fetch_array($q_location);
-						echo "<td><div class='entry' id='festival_entry_map'>\n";
-						echo "<h3 class='entry_title'>$lng[index_festivals_location]</h3>\n";
-						echo "<iframe src='https://www.google.com/maps/embed/v1/place?key=AIzaSyCZHP7t2on_G3eyyoCTfhGAlDx1mJnX7iI&q=$r_location[lat],$r_location[lon]' allowfullscreen></iframe>\n";
-						echo "</div>\n";
-					}
-					
-					echo "</tr></table>\n";
-					echo "<table class='festival_section_table'><tr>\n";
-					
-					//GM schedule
-					$q_sch_curr = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 1 AND start > NOW() - INTERVAL 45 MINUTE AND start < NOW() + INTERVAL 30 MINUTE ORDER BY start LIMIT 1;");
-					$q_sch_next = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 1 AND start > NOW() AND start < NOW() + INTERVAL 240 MINUTE ORDER BY start LIMIT 1;");
-					if (mysqli_num_rows($q_sch_curr) > 0 || mysqli_num_rows($q_sch_next) > 0){
-						echo "<td><div class='entry festival_schedule'>\n";
-						echo "<h3 class='entry_title'>$lng[index_festivals_gm_schedule]</h3>\n";
+?>
+					<div class='section' id='festivals' itemscope itemtype='http://schema.org/Event'>
+						<meta itemprop='inLanguage' content='<?=$lang?>'/>
+						<meta itemprop='name' content='<?=$lng['index_festivals_header']?> <?=$year?>'/>
+						<meta itemprop='description' content='<?=$lng['index_festivals_header']?> <?=$year?>'/>
+						<meta itemprop='startDate' content='<?=$year?>-08-04'/>
+						<meta itemprop='endDate' content='<?=$year?>-08-09'/>
+						<meta itemprop='url' content='<?=$proto?><?=$http_host?>/lablanca/'/>
+						<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'><meta itemprop='address' itemprop='name' content='Vitoria-Gasteiz'/></span>
+						<h3 class='section_title'><?=$lng['index_festivals_header']?> <?=$year?></h3>
+						<div class='entry' id='festivals_summary'>
+<?php
 					
-						if (mysqli_num_rows($q_sch_curr) > 0){
-							$r_sch_curr = mysqli_fetch_array($q_sch_curr);
-							echo "<div id='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'><h4>$lng[index_festivals_schedule_now]</h4>\n";
-							echo "<meta itemprop='inLanguage' content='$lang'/>\n";
-							echo "<meta itemprop='name' content='$r_sch_curr[title]'/>\n";
-							echo "<meta itemprop='startDate' content='$r_sch_curr[isostart]'/>\n";
-							if (strlen($r_sch_curr['isoend']) > 0){
-								echo "<meta itemprop='endDate' content='$r_sch_curr[isoend]'/>\n";
-							}
-							echo("<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'><meta itemprop='address' content='Vitoria-Gasteiz'/><span>\n");
-							echo "<span class='title'>$r_sch_curr[title]\n</span>";
-							if (strlen($r_sch_curr["description"]) > 0 && $r_sch_curr["description"] != $r_sch_curr["title"]){
-								echo "<br/><span class='description'>$r_sch_curr[description]</span>\n";
-								echo "<meta itemprop='description' content='$r_sch_curr[description]'/>\n";
-							}
-							echo "<table class='location'><tr>\n";
-							echo "<td><a target='_blank' href='http://maps.google.com/maps?q=$r_sch_curr[lat],$r_sch_curr[lon]+(My+Point)&z=14&ll=$r_sch_curr[lat],$r_sch_curr[lon]'><img alt=' ' src='$proto$http_host/img/misc/pinpoint.png'/></a></td>\n"; 
-							//If name and address are the same, show only name
-							if ($r_sch_curr['place'] == $r_sch_curr['address']){
-								echo "<td>$r_sch_curr[place]</td></tr></table>\n";
-							}
-							else{
-								echo "<td>$r_sch_curr[place] <span class='address'>- $r_sch_curr[address]</span></td></tr></table>\n";
-							}
-							echo "</div\n>";
-						}
-						
-						if (mysqli_num_rows($q_sch_next) > 0){
-							$r_sch_next = mysqli_fetch_array($q_sch_next);
-							echo "<div id='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'><h4>$lng[index_festivals_schedule_next]</h4>\n";
-							echo "<meta itemprop='inLanguage' content='$lang'/>\n";
-							echo "<meta itemprop='name' content='$r_sch_next[title]'/>\n";
-							echo "<meta itemprop='startDate' content='$r_sch_next[isostart]'/>\n";
-							if (strlen($r_sch_curr['isoend']) > 0){
-								echo "<meta itemprop='endDate' content='$r_sch_next[isoend]'/>\n";
-							}
-							echo("<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'><meta itemprop='address' itemprop='name'>Vitoria-Gasteiz</meta></span>\n");
-							echo "<span class='title'>$r_sch_next[title] - $r_sch_next[st]\n</span>";
-							if (strlen($r_sch_next["description"]) > 0 && $r_sch_next["description"] != $r_sch_next["title"]){
-								echo "<br/><span class='description'>$r_sch_next[description]</span>\n";
-								echo "<meta itemprop='description' content='$r_sch_next[description]'/>\n";
-							}
-							echo "<table class='location'><tr>\n";
-							echo "<td><a target='_blank' href='http://maps.google.com/maps?q=$r_sch_next[lat],$r_sch_next[lon]+(My+Point)&z=14&ll=$r_sch_next[lat],$r_sch_next[lon]'><img alt=' ' src='$proto$http_host/img/misc/pinpoint.png'/></a></td>\n"; 
-							//If name and address are the same, show only name
-							if ($r_sch_next['place'] == $r_sch_next['address']){
-								echo "<td>$r_sch_next[place]</td></tr></table>\n";
-							}
-							else{
-								echo "<td>$r_sch_next[place] <span class='address'>- $r_sch_next[address]</span></td></tr></table>\n";
+							//Summary
+							$q_festivals = mysqli_query($con, "SELECT text_$lang AS text, summary_$lang AS summary, img FROM festival WHERE year = $year;");
+							if(mysqli_num_rows($q_festivals)){
+								$r_festivals = mysqli_fetch_array($q_festivals);
+								if ($r_festivals['img'] != ''){
+									echo("<meta itemprop='image' content='$proto$http_host/img/fiestas/$r_festivals[img]'/>\n");
+									echo("<img id='festivals_image' alt=' ' src='$proto$http_host/img/fiestas/$r_festivals[img]'/>\n");
+								}
+								if ($r_festivals['summary'] != ''){
+									echo "<span class='entry_title' id='festivals_summary_text'><br/>$r_festivals[summary]</span>\n";
+									echo "<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='$proto$http_host/lablanca/'>$lng[index_festivals_link]</a>\n";
+								}
+								else{
+									echo "<span id='festivals_summary_text'><br/>" . cutText($r_festivals['text'], 300, "$lng[index_read_more]", "$proto$http_host/lablanca/") . "</span>\n";
+								}
 							}
-							echo "</div\n>";
-						}
-						echo "</div></td>\n"; //close gm schedule entry;
-					}
+?>
+						</div> <!--festivals_summary - entry-->
+						<div id='festivals_schedule_table'>
+							<div id='festivals_schedule_row'>
+								<div class='festivals_schedule_cell'>
+<?php
+									//GM schedule
+									$q_sch_curr = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 1 AND start > NOW() - INTERVAL 45 MINUTE AND start < NOW() + INTERVAL 30 MINUTE ORDER BY start LIMIT 1;");
+									$q_sch_next = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 1 AND start > NOW() AND start < NOW() + INTERVAL 240 MINUTE ORDER BY start LIMIT 1;");
+
+									if (mysqli_num_rows($q_sch_curr) > 0 || mysqli_num_rows($q_sch_next) > 0){
+										echo("<div class='entry festival_schedule' id='festivals_gm'>\n");
+										echo("<h3 class='entry_title'>$lng[index_festivals_gm_schedule]</h3>\n");
 										
-					//city schedule
-					$q_sch_curr = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 0 AND start > NOW() - INTERVAL 45 MINUTE AND start < NOW() + INTERVAL 30 MINUTE ORDER BY start LIMIT 1;");
-					$q_sch_next = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 0 AND start > NOW() AND start < NOW() + INTERVAL 240 MINUTE ORDER BY start LIMIT 1;");
-					if (mysqli_num_rows($q_sch_curr) > 0 || mysqli_num_rows($q_sch_next) > 0){
-						echo "<td><div class='entry festival_schedule' >\n";
-						echo "<h3 class='entry_title'>$lng[index_festivals_city_schedule]</h3>\n";
-					
-						if (mysqli_num_rows($q_sch_curr) > 0){
-							$r_sch_curr = mysqli_fetch_array($q_sch_curr);
-							echo "<div class='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'><h4>$lng[index_festivals_schedule_now]</h4>\n";
-							echo "<meta itemprop='inLanguage' content='$lang'/>\n";
-							echo "<meta itemprop='name' content='$r_sch_curr[title]'/>\n";
-							echo "<meta itemprop='startDate' content='$r_sch_curr[isostart]'/>\n";
-							if (strlen($r_sch_curr['isoend']) > 0){
-								echo "<meta itemprop='endDate' content='$r_sch_curr[isoend]'/>\n";
-							}
-							echo("<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'><meta itemprop='address' itemprop='name'>Vitoria-Gasteiz</meta></span>\n");
-							echo "<span class='title'>$r_sch_curr[title]\n</span>";
-							if (strlen($r_sch_curr["description"]) > 0 && $r_sch_curr["description"] != $r_sch_curr["title"]){
-								echo "<br/><span class='description'>$r_sch_curr[description]</span>\n";
-								echo "<meta itemprop='description' content='$r_sch_curr[description]'/>\n";
-							}
-							echo "<table class='location'><tr>\n";
-							echo "<td><a target='_blank' href='http://maps.google.com/maps?q=$r_sch_curr[lat],$r_sch_curr[lon]+(My+Point)&z=14&ll=$r_sch_curr[lat],$r_sch_curr[lon]'><img alt=' ' src='$proto$http_host/img/misc/pinpoint.png'/></a></td>\n"; 
-							//If name and address are the same, show only name
-							if ($r_sch_curr['place'] == $r_sch_curr['address']){
-								echo "<td>$r_sch_curr[place]</td></tr></table>\n";
-							}
-							else{
-								echo "<td>$r_sch_curr[place] <span class='address'>- $r_sch_curr[address]</span></td></tr></table>\n";
-							}
-							echo "</div\n>";
-						}
+										if (mysqli_num_rows($q_sch_curr) > 0){
+											$r_sch_curr = mysqli_fetch_array($q_sch_curr);
+?>
+											<div class='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'>
+												<h4><?=$lng[index_festivals_schedule_now]?></h4>
+												<meta itemprop='inLanguage' content='<?=$lang?>'/>
+												<meta itemprop='name' content='<?=$r_sch_curr['title']?>'/>
+												<meta itemprop='startDate' content='<?=$r_sch_curr['isostart']?>'/>
+												<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'>
+													<meta itemprop='address' content='Vitoria-Gasteiz'/>
+												</span>
+<?php
+												if (strlen($r_sch_curr['isoend']) > 0){
+													echo("<meta itemprop='endDate' content='$r_sch_curr[isoend]'/>\n");
+												}
+?>
+												<div class='schedule_content'>
+													<span class='title'><?=$r_sch_curr['title']?></span>
+<?php
+													if (strlen($r_sch_curr["description"]) > 0 && $r_sch_curr["description"] != $r_sch_curr["title"]){
+														echo("<br/><p class='description'>$r_sch_curr[description]</p>\n");
+														echo("<meta itemprop='description' content='$r_sch_curr[description]'/>\n");
+													}
+?>
+													<table class='location'>
+														<tr>
+															<td>
+																<a target='_blank' href='http://maps.google.com/maps?q=<?=$r_sch_curr[lat]?>,<?=$r_sch_curr[lon]?>+(My+Point)&z=14&ll=<?=$r_sch_curr[lat]?>,<?=$r_sch_curr[lon]?>'>
+																	<img alt=' ' src='<?=$proto?><?=$http_host?>/img/misc/pinpoint.png'/>
+																</a>
+															</td>
+															<td>
+<?php
+																//If name and address are the same, show only name
+																if ($r_sch_curr['place'] == $r_sch_curr['address']){
+																	echo("$r_sch_curr[place]\n");
+																}
+																else{
+																	echo("$r_sch_curr[place] <br/><span class='address'> $r_sch_curr[address]</span>\n");
+																}
+?>
+															</td>
+														</tr>
+													</table>
+												</div> <!--.schedule_content  -->
+											</div> <!-- festival-event -->
+<?php
+										} // if (mysqli_num_rows($q_sch_curr) > 0)
+										if (mysqli_num_rows($q_sch_next) > 0){
+											$r_sch_next = mysqli_fetch_array($q_sch_next);
+?>
+											
+											<div class='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'>
+												<h4><?=$lng['index_festivals_schedule_next']?></h4>
+												<meta itemprop='inLanguage' content='<?=$lang?>'/>
+												<meta itemprop='name' content='<?=$r_sch_next['title']?>'/>
+												<meta itemprop='startDate' content='<?=$r_sch_next['isostart']?>'/>
+												<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'>
+													<meta itemprop='address' itemprop='name'>Vitoria-Gasteiz</meta>
+												</span>
+<?php
+												if (strlen($r_sch_curr['isoend']) > 0){
+													echo("<meta itemprop='endDate' content='$r_sch_next[isoend]'/>\n");
+												}
+?>
+												<div class='schedule_content'>
+													<span class='title'><?=$r_sch_next['title']?> - <?=$r_sch_next['st']?></span>
+<?php
+													if (strlen($r_sch_next["description"]) > 0 && $r_sch_next["description"] != $r_sch_next["title"]){
+														echo("<br/><p class='description'>$r_sch_next[description]</p>\n");
+														echo("<meta itemprclass='entry'op='description' content='$r_sch_next[description]'/>\n");
+													}
+?>
+													<table class='location'>
+														<tr>
+															<td>
+																<a target='_blank' href='http://maps.google.com/maps?q=<?=$r_sch_next[lat]?>,<?=$r_sch_next[lon]?>+(My+Point)&z=14&ll=<?=$r_sch_next[lat]?>,<?=$r_sch_next[lon]?>'>
+																	<img alt=' ' src='<?=$proto?><?=$http_host?>/img/misc/pinpoint.png'/>
+																</a>
+															</td>
+															<td>
+<?php
+																//If name and address are the same, show only name
+																if ($r_sch_next['place'] == $r_sch_next['address']){
+																	echo("$r_sch_next[place]\n");
+																}
+																else{
+																	echo("$r_sch_next[place] </br><span class='address'> $r_sch_next[address]</span>\n");
+																}
+?>
+															</td>
+														</tr>
+													</table>
+												</div> <!--.schedule_content  -->
+											</div> <!-- festival-event -->
+<?php
+										}
+?>
+										</div> <!--festivals_gm-->
+<?php
+									} // if (mysqli_num_rows($q_sch_curr) > 0 || ysqli_num_rows($q_sch_next) > 0)
+?>
+								</div> <!-- festivals_schedule_cell -->
+								<div class='festivals_schedule_cell'>
+<?php
+												
+									//City schedule
+									$q_sch_curr = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 0 AND start > NOW() - INTERVAL 45 MINUTE AND start < NOW() + INTERVAL 30 MINUTE ORDER BY start LIMIT 1;");
+									$q_sch_next = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, DATE_FORMAT(start, '%Y-%m-%dT%H:%i:00') AS isostart, DATE_FORMAT(end, '%Y-%m-%dT%H:%i:00') AS isoend, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 0 AND start > NOW() AND start < NOW() + INTERVAL 240 MINUTE ORDER BY start LIMIT 1;");
+									if (mysqli_num_rows($q_sch_curr) > 0 || mysqli_num_rows($q_sch_next) > 0){
+										echo "<div class='entry festival_schedule' id='festivals_city'>\n";
+										
+										echo "<h3 class='entry_title'>$lng[index_festivals_city_schedule]</h3>\n";
+									
+										if (mysqli_num_rows($q_sch_curr) > 0){
+											$r_sch_curr = mysqli_fetch_array($q_sch_curr);
+?>
+											<div class='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'>
+												<h4><?=$lng['index_festivals_schedule_now']?></h4>
+												<meta itemprop='inLanguage' content='<?=$lang?>'/>
+												<meta itemprop='name' content='<?=$r_sch_curr['title']?>'/>
+												<meta itemprop='startDate' content='<?=$r_sch_curr['isostart']?>'/>
+												<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'>
+													<meta itemprop='address' itemprop='name'>Vitoria-Gasteiz</meta>
+												</span>
+<?php
+												if (strlen($r_sch_curr['isoend']) > 0){
+													echo("<meta itemprop='endDate' content='$r_sch_curr[isoend]'/>\n");
+												}
+?>
+												<div class='schedule_content'>
+													<span class='title'><?=$r_sch_curr['title']?></span>
+<?php
+
+													if (strlen($r_sch_curr["description"]) > 0 && $r_sch_curr["description"] != $r_sch_curr["title"]){
+														echo("<br/><p class='description'>$r_sch_curr[description]</p>\n");
+														echo("<meta itemprop='description' content='$r_sch_curr[description]'/>\n");
+													}
+?>
+													<table class='location'>
+														<tr>
+															<td>
+																<a target='_blank' href='http://maps.google.com/maps?q=<?=$r_sch_curr[lat]?>,<?=$r_sch_curr[lon]?>+(My+Point)&z=14&ll=<?=$r_sch_curr[lat]?>,<?=$r_sch_curr[lon]?>'>
+																	<img alt=' ' src='<?=$proto?><?=$http_host?>/img/misc/pinpoint.png'/>
+																</a>
+															</td>
+															<td>
+<?php
+																//If name and address are the same, show only name
+																if ($r_sch_curr['place'] == $r_sch_curr['address']){
+																	echo("$r_sch_curr[place]\n");
+																}
+																else{
+																	echo("$r_sch_curr[place] <br/><span class='address'> $r_sch_curr[address]</span>\n");
+																}
+?>
+															</td>
+														</tr>
+													</table>
+												</div> <!--.schedule_content  -->
+											</div> <!-- festival-event -->
+<?php
+										}
+
+										
+										if (mysqli_num_rows($q_sch_next) > 0){
+											$r_sch_next = mysqli_fetch_array($q_sch_next);
+?>
+											<div class='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'>
+												<h4><?=$lng['index_festivals_schedule_next']?></h4>
+												<meta itemprop='inLanguage' content='<?=$lang?>'/>
+												<meta itemprop='name' content='<?=$r_sch_next['title']?>'/>
+												<meta itemprop='startDate' content='<?=$r_sch_next['isostart']?>'/>
+												<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'>
+													<meta itemprop='address' itemprop='name'>Vitoria-Gasteiz</meta>
+												</span>
+<?php
+												if (strlen($r_sch_curr['isoend']) > 0){
+													echo "<meta itemprop='endDate' content='$r_sch_next[isoend]'/>\n";
+												}
+?>
+												<div class='schedule_content'>
+													<span class='title'><?=$r_sch_next['title']?> - <?=$r_sch_next['st']?></span>
+<?php
+													if (strlen($r_sch_next["description"]) > 0 && $r_sch_next["description"] != $r_sch_next["title"]){
+														echo "<br/><p class='description'>$r_sch_next[description]</p>\n";
+														echo "<meta itemprop='description' content='$r_sch_next[description]'/>\n";
+													}
+?>
+													<table class='location'>
+														<tr>
+															<td>
+																<a target='_blank' href='http://maps.google.com/maps?q=<?=$r_sch_next[lat]?>,<?=$r_sch_next[lon]?>+(My+Point)&z=14&ll=<?=$r_sch_next[lat]?>,<?=$r_sch_next[lon]?>'>
+																	<img alt=' ' src='<?=$proto?><?=$http_host?>/img/misc/pinpoint.png'/>
+																</a>
+															</td>
+															<td>
+<?php
+																//If name and address are the same, show only name
+																if ($r_sch_next['place'] == $r_sch_next['address']){
+																	echo("$r_sch_next[place]\n");
+																}
+																else{
+																	echo("$r_sch_next[place] <br/><span class='address'> $r_sch_next[address]</span>\n");
+																}
+?>
+															</td>
+														</tr>
+													</table>
+												</div> <!--.schedule_content  -->
+											</div> <!-- festival-event -->
+<?php
+										}
+?>
+										</div> <!--festivals_schedule-->
+<?php
+									}
+?>
+								</div> <!-- festivals_schedule_cell -->
+							</div> <!-- festivals_schedule_row -->
+						</div> <!-- festivals_schedule_table -->
+						<a class='go_to_section' href='<?=$proto?><?=$http_host?>/lablanca/'><?=$lng['index_festivals_link']?></a>
+						<br/>
 						
-						if (mysqli_num_rows($q_sch_next) > 0){
-							$r_sch_next = mysqli_fetch_array($q_sch_next);
-							echo "<div class='festival_event' itemprop='subEvent' itemscope itemtype='http://schema.org/Event'><h4>$lng[index_festivals_schedule_next]</h4>\n";
-							echo "<meta itemprop='inLanguage' content='$lang'/>\n";
-							echo "<meta itemprop='name' content='$r_sch_next[title]'/>\n";
-							echo "<meta itemprop='startDate' content='$r_sch_next[isostart]'/>\n";
-							if (strlen($r_sch_curr['isoend']) > 0){
-								echo "<meta itemprop='endDate' content='$r_sch_next[isoend]'/>\n";
-							}
-							echo("<span class='hidden' itemprop='location' itemscope itemtype='http://schema.org/Place'><meta itemprop='address' itemprop='name'>Vitoria-Gasteiz</meta></span>\n");
-							echo "<span class='title'>$r_sch_next[title] - ($r_sch_next[st])\n</span>";
-							if (strlen($r_sch_next["description"]) > 0 && $r_sch_next["description"] != $r_sch_next["title"]){
-								echo "<br/><span class='description'>$r_sch_next[description]</span>\n";
-								echo "<meta itemprop='description' content='$r_sch_next[description]'/>\n";
-							}
-							echo "<table class='location'><tr>\n";
-							echo "<td><a target='_blank' href='http://maps.google.com/maps?q=$r_sch_next[lat],$r_sch_next[lon]+(My+Point)&z=14&ll=$r_sch_next[lat],$r_sch_next[lon]'><img alt=' ' src='$proto$http_host/img/misc/pinpoint.png'/></a></td>\n"; 
-							//If name and address are the same, show only name
-							if ($r_sch_next['place'] == $r_sch_next['address']){
-								echo "<td>$r_sch_next[place]</td></tr></table>\n";
-							}
-							else{
-								echo "<td>$r_sch_next[place] <span class='address'>- $r_sch_next[address]</span></td></tr></table>\n";
-							}
-							echo "</div\n>";
-						}
-						echo "</div></td>\n"; //close city schedule entry;
-					}
-					echo "</tr></table>\n";
-					echo "<a class='go_to_section' href='$proto$http_host/lablanca/'>$lng[index_festivals_link]</a><br/>\n";
-					echo "</div>\n";
+					</div> <!-- festivals - section-->
+<?php
 				}
 			
 				//Upcaming activity section
@@ -315,7 +426,7 @@
 					echo "<a class='go_to_section' href='$proto$http_host/actividades/'>$lng[index_upcoming_activity_see_all]</a><br/>\n";
 					echo "</div>\n";//Section
 				}
-			?>
+?>
 			<div class='section' itemscope itemtype='http://schema.org/Organization'>
 				<meta itemprop='url' content='<?php echo("$proto$http_host"); ?>'/>
 				<h3 class='section_title' itemprop='name'><?php echo($lng['index_us']); ?></h3>
@@ -330,7 +441,7 @@
 				<div class='content_row'>
 					<div class='content_cell' id='cell_posts'>
 						<div class='section' id='latest_posts'>
-							<?php
+		<?php
 								echo "<h3 class='section_title'>$lng[index_latest_posts]</h3>\n";
 								$q_post = mysqli_query($con, "SELECT id, permalink, title_$lang AS title, text_$lang AS text, dtime, DATE_FORMAT(dtime, '%Y-%m-%dT%T') AS isodate FROM post WHERE visible = 1 ORDER BY dtime DESC LIMIT 2;");
 								if (mysqli_num_rows($q_post) == 0){
@@ -365,12 +476,12 @@
 									}
 								echo "<a class='go_to_section' href='$proto$http_host/blog/'>$lng[index_see_all_posts]</a><br/>\n";
 								}
-							?>
+		?>
 						</div>
 					</div>
 					<div class='content_cell' id='cell_photos'>
 						<div class='section' id='latest_photos'>
-							<?php
+		<?php
 								echo "<h3 class='section_title'>$lng[index_latest_photos]</h3>\n";
 								$q_photos = mysqli_query($con, "SELECT id, file, title_$lang AS title, DATE_FORMAT(uploaded, '%Y-%m-%d') AS isodate FROM photo ORDER BY uploaded DESC LIMIT 6;");
 								//TODO WHERE approved = 1
@@ -399,12 +510,12 @@
 									echo "</div>\n";
 									echo "<a class='go_to_section' href='$proto$http_host/galeria/'>$lng[index_see_all_photos]</a><br/>\n";
 								}
-							?>
+		?>
 						</div>
 					</div>
 				</div>
 			</div>
-			<?php
+<?php
 				if ($upcoming_activity_shown == false){
 					$q_activity = mysqli_query($con, "SELECT id, permalink, date, DATE_FORMAT(date, '%Y-%m-%d') AS isodate, title_$lang AS title, text_$lang AS text, after_$lang AS after, price, inscription, people, max_people, city FROM activity WHERE visible = 1 ORDER BY date DESC LIMIT 2;");
 					if (mysqli_num_rows($q_activity) > 0){
@@ -455,23 +566,23 @@
 				}
 				//Festivals section (if no festivals shown on top)
 				if ($festivals == 0){
-					?>
+?>
 						<div class='section'>
 							<h3 class='section_title'><?php echo($lng['index_festivals_header']); ?></h3>
 							<div class='entry'>
-							<?php echo (cutText($lng['lablanca_no_content'] . '<br/>' . $lng['lablanca_no_content_2'], 300, "$lng[index_read_more]", "$proto$http_host/lablanca/")); ?>
+		<?php echo (cutText($lng['lablanca_no_content'] . '<br/>' . $lng['lablanca_no_content_2'], 300, "$lng[index_read_more]", "$proto$http_host/lablanca/")); ?>
 							</div>
 						</div>
-					<?php
+<?php
 				}
-			?>
+?>
 		</div>
-		<?php
+<?php
 
 			//Footer
 			include("footer.php");
 			$ad = ad($con, $lang, $lng); 
 			stats($ad, $ad_static, "index", "");
-		?>
+?>
 	</body>
 </html>

+ 64 - 46
www/lablanca/fiestas.php

@@ -1,64 +1,82 @@
 <div class='section'>
-	<h3 class='section_title'><?php echo str_replace('#', $year, $lng['lablanca_title']);?></h3>
+	<h3 class='section_title'><?=str_replace('#', $year, $lng['lablanca_title'])?></h3>
 	<div class='entry'>
-	<?php
-		//Some text for the festivals
-		$q_f = mysqli_query($con, "SELECT * FROM festival WHERE year = $year");
-		if (mysqli_num_rows($q_f) > 0){
-			$r_f = mysqli_fetch_array($q_f);
-			if (strlen($r_f['img']) > 0){
-				echo "<img id='festivals_image' src='$proto$http_host/img/festival/$r_f[img]'>\n";
-			}
-			echo $r_f["text_$lang"] . "\n";
+<?php
+	//Some text for the festivals
+	$q_f = mysqli_query($con, "SELECT * FROM festival WHERE year = $year");
+	if (mysqli_num_rows($q_f) > 0){
+		$r_f = mysqli_fetch_array($q_f);
+		if (strlen($r_f['img']) > 0){
+			echo("<div id='festivals_image_top_container'><div id='festivals_image_container'><img id='festivals_image' src='$proto$http_host/img/fiestas/preview/$r_f[img]'/></div></div><br/>\n");
 		}
-	?>
+		echo $r_f["text_$lang"] . "\n";
+	}
+?>
 	</div>
 </div>
 <div id='content_table'>
 	<div class='content_tr'>
 		<div class='content_td' id='content_td_schedule'>
 			<div class='section' id='schedule'>
-				<h3 class='section_title'><?php echo $lng['lablanca_schedule']; ?></h3>
-					<?php
-						$q_days = mysqli_query($con, "SELECT id, date, DATE_FORMAT(date, '%Y-%m-%d') AS isodate, name_$lang AS name FROM festival_day WHERE year(date) = $year ORDER BY date");
-						while ($r_days = mysqli_fetch_array($q_days)){
-							echo "<div class='entry'>\n";
-							echo "<div onClick='expandDay($r_days[id]);' class='day_title pointer'>\n";
-							echo "<h4><img class='slid' src='$proto$http_host/img/misc/slid-right.png' id='slid_day_$r_days[id]'/>\n";
-							echo formatFestivalDate($r_days['date']) . " - $r_days[name]</h4>\n";
-							echo "</div>\n";
-							echo "<div class='day_schedule' id='day_schedule_$r_days[id]'>\n";
+				<h3 class='section_title'><?=$lng['lablanca_schedule']?></h3>
+<?php
+				$q_days = mysqli_query($con, "SELECT id, date, DATE_FORMAT(date, '%Y-%m-%d') AS isodate, name_$lang AS name FROM festival_day WHERE year(date) = $year ORDER BY date");
+				while ($r_days = mysqli_fetch_array($q_days)){
+?>
+					<div class='entry'>
+						<div onClick='expandDay(<?=$r_days['id']?>);' class='day_title pointer'>
+							<h4>
+								<img class='slid' src='<?=$server?>/img/misc/slid-right.png' id='slid_day_<?=$r_days['id']?>'/>
+								<?=formatFestivalDate($r_days['date'])?> - <?=$r_days['name']?>
+							</h4>
+						</div>
+						<div class='day_schedule' id='day_schedule_<?=$r_days['id']?>'>
+<?php
 							$q_sch = mysqli_query($con, "SELECT festival_event.id AS id, gm, title_$lang AS title, description_$lang AS description, host, place, date_format(start, '%H:%i') AS st, date_format(end, '%H:%i') AS end, place.name_$lang AS place, address_$lang AS address, lat, lon FROM festival_event, place WHERE place.id = festival_event.place AND gm = 1 AND start > str_to_date(addtime('$r_days[isodate] 00:00:00', '08:00:00'), '%Y-%m-%d %T') AND start < str_to_date(addtime('$r_days[isodate] 00:00:00', '32:00:00'), '%Y-%m-%d %T') ORDER BY start;");
 							if (mysqli_num_rows($q_sch) > 0){
-								echo "<table class='schedule'>\n";
+								echo("<table class='schedule'>\n");
 								while ($r_sch = mysqli_fetch_array($q_sch)){
-									echo "<tr><td><span class='time'>$r_sch[st]</span></td><td class='timeline'><img class='timeline_dot' alt=' ' src='$proto$http_host/img/misc/schedule-point.png'/></td>\n";
-									echo "<td><span class='title'>$r_sch[title]\n";
-									//if (strlen($r_sch['end']) > 0){
-									//	echo " ($r_sch[st] - $r_sch[end])\n";
-									//}
-									echo "</span>\n";
-									if (strlen($r_sch["description"]) > 0 && $r_sch["description"] != $r_sch["title"]){
-										echo "<br/><span class='description'>$r_sch[description]</span>\n";
-									}
-									echo "<table class='location'><tr>\n";
-									//TODO: td for image, if any
-									echo "<td><a target='_blank' href='http://maps.google.com/maps?q=$r_sch[lat],$r_sch[lon]+(My+Point)&z=14&ll=$r_sch[lat],$r_sch[lon]'><img alt=' ' src='$proto$http_host/img/misc/pinpoint.png'/></a></td>\n"; 
-									//If name and address are the same, show only name
-									if ($r_sch['place'] == $r_sch['address']){
-										echo "<td>$r_sch[place]</td></tr></table>\n";
-									}
-									else{
-										echo "<td>$r_sch[place] <span class='address'>- $r_sch[address]</span></td></tr></table>\n";
-									}
-									echo "</td></tr>\n";
+?>
+									<tr>
+										<td>
+											<span class='time'><?=$r_sch['st']?></span>
+										</td>
+										<td class='timeline'>
+											<img class='timeline_dot' alt=' ' src='<?=$server?>/img/misc/schedule-point.png'/>
+										</td>
+										<td>
+											<span class='title'><?=$r_sch['title']?></span>
+<?php
+											if (strlen($r_sch["description"]) > 0 && $r_sch["description"] != $r_sch["title"]){
+												echo("<br/><div class='description'>$r_sch[description]</div>\n");
+											}
+?>
+											<div class='location'>
+												<a target='_blank' href='http://maps.google.com/maps?q=<?=$r_sch['lat']?>,<?=$r_sch['lon']?>+(My+Point)&z=14&ll=<?=$r_sch['lat']?>,<?=$r_sch['lon']?>'>
+													<img alt=' ' src='<?=$server?>/img/misc/pinpoint.png'/>
+<?php
+													//If name and address are the same, show only name
+													if ($r_sch['place'] == $r_sch['address']){
+														echo("$r_sch[place]\n");
+													}
+													else{
+														echo("$r_sch[place] <span class='address'>- $r_sch[address]</span>\n");
+													}
+?>
+												</a>
+											</div>
+										</td>
+									</tr>
+<?php
 								}
 								echo "</table>\n";
 							}
-							echo "</div>\n";
-							echo "</div>\n";
-						}
-					?>
+?>
+						</div>
+					</div>
+<?php
+				} // while ($r_days = mysqli_fetch_array($q_days))
+?>
 			</div>
 		</div>
 		<div class='content_td' id='content_td_prices'>

+ 2 - 0
www/lablanca/index.php

@@ -3,6 +3,8 @@
 	include("../functions.php");
 	$con = startdb();
 	$proto = getProtocol();
+	$http_host = $_SERVER['HTTP_HOST'];
+	$server = "$proto" . "$http_host";
 	
 	//Language
 	$lang = selectLanguage();

Файловите разлики са ограничени, защото са твърде много
+ 0 - 1
www/lang/lang_en.php


Файловите разлики са ограничени, защото са твърде много
+ 0 - 1
www/lang/lang_eu.php


+ 372 - 0
www/traducir/index.php

@@ -0,0 +1,372 @@
+<?php
+	session_start();
+	$http_host = $_SERVER['HTTP_HOST'];
+	include("../functions.php");
+	$proto = getProtocol();
+	$con = startdb();
+	$server = "$proto$http_host";
+
+	//Language
+	$lang = 'es';
+	include("../lang/lang_es.php");
+
+	$cur_section = 'Traducciones';
+
+	$l = strtolower(mysqli_real_escape_string($con, $_GET['l'])); // language
+	if ($l != 'en' && $l != 'eu'){
+?>
+		<!DOCTYPE html>
+			<html>
+				<head>
+					<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
+					<meta charset="utf-8"/>
+					<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
+					<title>Traducciones - Gasteizko Margolariak</title>
+					<link rel="shortcut icon" href="<?=$server?>/img/logo/favicon.ico">
+					<!-- CSS files -->
+					<style>
+<?php
+							include("../css/ui.css"); 
+							include("../css/traducir.css");
+?>
+					</style>
+					<!-- CSS for mobile version -->
+					<style media="(max-width : 990px)">
+<?php
+							include("../css/m/ui.css"); 
+							include("../css/m/traducir.css");
+?>
+					</style>
+					<!-- Script files -->
+					<script type="text/javascript">
+<?php
+						include("../script/ui.js");
+?>
+					</script>
+					<!-- Meta tags -->
+					<link rel="canonical" href="<?=$server?>/traducir/"/>
+					<link rel="author" href="<?=server?>"/>
+					<link rel="publisher" href="<?=server?>"/>
+					<meta name="description" content="Traduccion de contenidos de la web de Gasteizko Margolariak"/>
+					<meta property="og:title" content="Traducciones - Gasteizko Margolariak"/>
+					<meta property="og:url" content="<?=$server?>/traducir/"/>
+					<meta property="og:description" content="Traduccion de contenidos de la web de Gasteizko Margolariak"/>
+					<meta property="og:image" content="<?=$server?>/img/logo/logo.png"/>
+					<meta property="og:site_name" content="Gasteizko Margolariak"/>
+					<meta property="og:type" content="website"/>
+					<meta property="og:locale" content="es"/>
+					<meta name="twitter:card" content="summary"/>
+					<meta name="twitter:title" content="Traducciones - Gasteizko Margolariak"/>
+					<meta name="twitter:description" content="Traduccion de contenidos de la web de Gasteizko Margolariak"/>
+					<meta name="twitter:image" content="<?=$server?>/img/logo/logo.png"/>
+					<meta name="twitter:url" content="<?$server?>/traducir/"/>
+					<meta name="robots" content="noindex nofollow"/>
+				</head>
+				<body>
+<?php				include("../header.php"); ?>
+					<div id="content">
+						<div class='section' id='w_init'>
+							<h3 class='section_title'>Traducciones</h3>
+							<div class='entry'>
+								<a class='lang' href='<?=$server?>/traducir/eu/'>Traducir al euskera</a>
+								<a class='lang' href='<?=$server?>/traducir/en/'>Traducir al ingl&eacute;s</a>
+							</div>
+						</div>
+					</div>
+				</body>
+			</html>
+<?php
+	}
+	else{
+		$q_string="
+		SELECT * FROM (
+		SELECT * FROM (
+		SELECT 'activity' AS tab, 'title' AS field, id, title_es AS es, title_eu AS eu, title_en AS en, dtime FROM activity WHERE title_es = title_XX
+		UNION
+		SELECT 'activity' AS tab, 'text' AS field, id, text_es AS es, text_eu AS eu, text_en AS en, dtime FROM activity WHERE text_es = text_XX
+		UNION
+		SELECT 'activity' AS tab, 'after' AS field, id, after_es AS es, after_eu AS eu, after_en AS en, dtime FROM activity WHERE after_es IS NOT NULL AND after_es = after_XX
+		UNION
+		SELECT 'activity_itinerary' AS tab, 'name' AS field, activity_itinerary.id AS id, name_es AS es, name_eu AS eu, name_en AS en, dtime FROM activity, activity_itinerary WHERE activity = activity.id AND name_es = name_XX
+		UNION
+		SELECT 'activity_itinerary' AS tab, 'text' AS field, activity_itinerary.id AS id, text_es AS es, text_eu AS eu, text_en AS en, dtime FROM activity, activity_itinerary WHERE activity = activity.id AND text_es IS NOT null AND text_es = text_XX
+		UNION
+		SELECT 'album' AS tab, 'title' AS field, id, title_es AS es, title_eu AS eu, title_en AS en, dtime FROM album WHERE title_es = title_XX
+		UNION
+		SELECT 'album' AS tab, 'description' AS field, id, description_es AS es, description_eu AS eu, description_en AS en, dtime FROM album WHERE description_es IS NOT NULL AND description_es = description_XX
+		UNION
+		SELECT 'festival' AS tab, 'text' AS field, id, text_es AS es, text_eu AS eu, text_en AS en, str_to_date(year || '-' || month(sysdate()) || '-' || day(sysdate()), '%Y-%m-%d') AS dtime FROM festival WHERE text_es = text_XX
+		UNION
+		SELECT 'festival' AS tab, 'summary' AS field, id, summary_es AS es, summary_eu AS eu, summary_en AS en, str_to_date(year || '-' || month(sysdate()) || '-' || day(sysdate()), '%Y-%m-%d') AS dtime FROM festival WHERE summary_es IS NOT null AND summary_es = summary_XX
+		UNION
+		SELECT 'festival_day' AS tab, 'name' AS field, id AS id, name_es AS es, name_eu AS eu, name_en AS en, date AS dtime FROM festival_day WHERE name_es = name_XX
+		UNION
+		SELECT 'festival_event' AS tab, 'title' AS field, id, title_es AS es, title_eu AS eu, title_en AS en, start AS dtime FROM festival_event WHERE title_es = title_XX
+		UNION
+		SELECT 'festival_event' AS tab, 'description' AS field, id, description_es AS es, description_eu AS eu, description_en AS en, start AS dtime FROM festival_event WHERE description_es IS NOT null AND description_es = description_XX
+		UNION
+		SELECT 'festival_offer' AS tab, 'name' AS field, id AS id, name_es AS es, name_eu AS eu, name_en AS en, str_to_date(year || '-' || month(sysdate()) || '-' || day(sysdate()), '%Y-%m-%d') AS dtime FROM festival_offer WHERE name_es = name_XX
+		UNION
+		SELECT 'festival_offer' AS tab, 'description' AS field, id AS id, description_es AS es, description_eu AS eu, description_en AS en, str_to_date(year || '-' || month(sysdate()) || '-' || day(sysdate()), '%Y-%m-%d') AS dtime FROM festival_offer WHERE description_es IS NOT null AND description_es = description_XX
+		UNION
+		SELECT 'photo' AS tab, 'title' AS field, id, title_es AS es, title_eu AS eu, title_en AS en, dtime FROM photo WHERE title_es IS NOT null AND title_es = title_XX
+		UNION
+		SELECT 'photo' AS tab, 'description' AS field, id, description_es AS es, description_eu AS eu, description_en AS en, dtime FROM photo WHERE description_es IS NOT null AND description_es = description_XX
+		UNION
+		SELECT 'place' AS tab, 'name' AS field, id AS id, name_es AS es, name_eu AS eu, name_en AS en, DATE_SUB(sysdate(), INTERVAL 7 DAY) AS dtime FROM place WHERE name_es = name_XX
+		UNION
+		SELECT 'place' AS tab, 'address' AS field, id AS id, address_es AS es, address_eu AS eu, address_en AS en, DATE_SUB(sysdate(), INTERVAL 7 DAY) AS dtime FROM place WHERE address_es = address_XX
+		UNION
+		SELECT 'post' AS tab, 'title' AS field, id, title_es AS es, title_eu AS eu, title_en AS en, dtime FROM post WHERE title_es = title_XX
+		UNION
+		SELECT 'post' AS tab, 'text' AS field, id, text_es AS es, text_eu AS eu, text_en AS en, dtime FROM post WHERE text_es = text_XX
+		UNION
+		SELECT 'sponsor' AS tab, 'name' AS field, id AS id, name_es AS es, name_eu AS eu, name_en AS en, DATE_SUB(sysdate(), INTERVAL 8 DAY) AS dtime FROM sponsor WHERE name_es = name_XX
+		UNION
+		SELECT 'sponsor' AS tab, 'text' AS field, id AS id, text_es AS es, text_eu AS eu, text_en AS en, DATE_SUB(sysdate(), INTERVAL 8 DAY) AS dtime FROM sponsor WHERE text_es = text_XX
+		UNION
+		SELECT 'sponsor' AS tab, 'address' AS field, id AS id, address_es AS es, address_eu AS eu, address_en AS en, DATE_SUB(sysdate(), INTERVAL 8 DAY) AS dtime FROM sponsor WHERE address_es = address_XX
+		) d ORDER BY dtime DESC LIMIT 100
+		) f ORDER BY rand();
+		";
+
+		// Select language
+		$q_string = str_replace('XX', $l, $q_string);
+	
+?>
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
+		<meta charset="utf-8"/>
+		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
+		<title>Traducciones - Gasteizko Margolariak</title>
+		<link rel="shortcut icon" href="<?=$server?>/img/logo/favicon.ico">
+		<!-- CSS files -->
+		<style>
+<?php 
+				include("../css/ui.css"); 
+				include("../css/traducir.css");
+?>
+		</style>
+		<!-- CSS for mobile version -->
+		<style media="(max-width : 990px)">
+<?php
+				include("../css/m/ui.css"); 
+				include("../css/m/traducir.css");
+?>
+		</style>
+		<!-- Script files -->
+		<script type="text/javascript">
+<?php
+ 			include("../script/ui.js");
+?>
+			var table = [];
+			var field = [];
+			var id = [];
+			var es = [];
+			var en = [];
+			var eu = [];
+			var idx = 0;
+
+<?php
+			$q = mysqli_query($con, $q_string);
+			$i = 0;
+			while ($r = mysqli_fetch_array($q)){
+				// Populate arrays
+?>
+				table[<?=$i?>] = '<?=$r['tab']?>';
+				field[<?=$i?>] = '<?=$r['field']?>';
+				id[<?=$i?>] = '<?=$r['id']?>';
+				es[<?=$i?>] = '<?=str_replace("'", "´", $r['es'])?>';
+				en[<?=$i?>] = '<?=str_replace("'", "´", $r['en'])?>';
+				eu[<?=$i?>] = '<?=str_replace("'", "´", $r['eu'])?>';
+<?php
+				$i = $i + 1;
+			}
+
+?>
+
+			function prepare(){
+				while (es[idx].length == 0){
+					idx = idx + 1;
+				}
+				if (es[idx].length <= 180){
+					document.getElementById('i_original').innerHTML = es[idx];
+					document.getElementById('i_original').style.display = 'inline-block';
+					document.getElementById('i_translation').value = '';
+					document.getElementById('i_translation').style.display = 'inline-block';
+					document.getElementById('t_original').innerHTML = '';
+					document.getElementById('t_original').style.display = 'none';
+					document.getElementById('t_translation').innerHTML = '';
+					document.getElementById('t_translation').innerText = '';
+					document.getElementById('t_translation').value = '';
+					document.getElementById('t_translation').style.display = 'none';
+					document.getElementById('type').value = 'i';
+				}
+				else{
+					document.getElementById('i_original').innerHTML = '';
+					document.getElementById('i_original').style.display = 'none';
+					document.getElementById('i_translation').value = '';
+					document.getElementById('i_translation').style.display = 'none';
+					document.getElementById('t_original').innerHTML = es[idx];
+					document.getElementById('t_original').style.display = 'inline-block';
+					document.getElementById('t_translation').innerHTML = '';
+					document.getElementById('t_translation').innerText = '';
+					document.getElementById('t_translation').value = '';
+					document.getElementById('t_translation').style.display = 'inline-block';
+					document.getElementById('type').value = 't';
+				}
+			}
+			
+			function error(title, text){
+				document.getElementById('error_title').innerHTML = title;
+				document.getElementById('error_msg').innerHTML = text;
+				document.getElementById('w_error').style.display = 'block';
+				document.getElementById('w_error').style.opacity = 1;
+			}
+			
+			function closeError(){
+				document.getElementById('w_error').style.opacity = 0;
+				setTimeout(function(){ document.getElementById('w_error').style.display = 'none'; }, 500);
+			}
+			
+			function save(){
+				if (document.getElementById('name').value.length == 0){
+					error("Introduce tu nombre.", "Es necesario un nombre para identificar de quien provienen las traducciones.");
+					return;
+				}
+				if (((document.getElementById('type').value == 'i') && (document.getElementById('i_translation').value.length == 0)) || ((document.getElementById('type').value == 't') && (document.getElementById('t_translation').value.length == 0))){
+					error("Introduce una traducci&oacute;n.", "No has introducido una traducci&oacute;n. Si lo prefieres, utiliza el boton rojo para saltar esta traducci&oacute;n.");
+					return;
+				}
+				
+				// Get data
+				var t = encodeURI(table[idx]);
+				var f = encodeURI(field[idx]);
+				var i = encodeURI(id[idx]);
+				var c = "";
+				var l = "<?=$l?>";
+				var n = document.getElementById('name').value;
+				if (document.getElementById('type').value == 'i'){
+					c = encodeURI(document.getElementById('i_translation').value);
+				}
+				else{
+					c = encodeURI(document.getElementById('t_translation').value);
+				}
+				var url = "<?=$server?>/traducir/load.php?t=" + t + "&f=" + f + "&i=" + i + "&c=" + c + "&l=" + l + "&n=" + n;
+				var xhttp = new XMLHttpRequest();
+				xhttp.onreadystatechange = function() {
+					// I won't notify  400 status code. I dont' want to be anoying.
+					if (this.readyState == 4 && (this.status == 200 || this.status == 400)) {
+						next();
+					}
+				};
+				xhttp.open("GET", url, true);
+				xhttp.send();
+			}
+
+			function next(){
+				idx = idx + 1;
+				prepare();
+			}
+
+		</script>
+		<!-- Meta tags -->
+		<link rel="canonical" href="<?=$server?>/traducir/"/>
+		<link rel="author" href="<?=$server?>"/>
+		<link rel="publisher" href="<?=$server?>"/>
+		<meta name="description" content="Traduccion de contenidos de la web de Gasteizko Margolariak"/>
+		<meta property="og:title" content="Traducciones - Gasteizko Margolariak"/>
+		<meta property="og:url" content="<?=$server?>/traducir/"/>
+		<meta property="og:description" content="Traduccion de contenidos de la web de Gasteizko Margolariak"/>
+		<meta property="og:image" content="<?=$server?>/img/logo/logo.png"/>
+		<meta property="og:site_name" content="Gasteizko Margolariak"/>
+		<meta property="og:type" content="website"/>
+		<meta property="og:locale" content="es"/>
+		<meta name="twitter:card" content="summary"/>
+		<meta name="twitter:title" content="Traducciones - Gasteizko Margolariak"/>
+		<meta name="twitter:description" content="Traduccion de contenidos de la web de Gasteizko Margolariak"/>
+		<meta name="twitter:image" content="<?=$server?>/img/logo/logo.png"/>
+		<meta name="twitter:url" content="<?=$server?>/traducir/"/>
+		<meta name="robots" content="noindex nofollow"/>
+	</head>
+	<body onLoad='prepare();'>
+<?php	 include("../header.php"); ?>
+		<div id="content">
+			<div class='section'>
+				<h3 class='section_title'>Traducciones en 
+<?php
+					if ($l == 'en'){
+						echo("ingl&eacute;s");
+					}
+					else{
+						echo("euskera");
+					}
+?>
+				</h3>
+				<div class='entry' id='w_target'>
+					<div class='translation' id='original'>
+						<h3 class='entry_title'>Original (Castellano)</h3>
+						<span id='i_original'></span>
+						<p id='t_original'></p>
+					</div>
+					<div class='translation' id='translation'>
+						<h3 class='entry_title'>Traducci&oacute;n (
+<?php
+							if ($l == 'en'){
+								echo("Ingl&eacute;s");
+							}
+							else{
+								echo("Euskera");
+							}
+?>
+						)</h3>
+						<input type='text' id='i_translation'/>
+						<textarea id='t_translation'></textarea>
+					</div>
+					<input type='hidden' id='type' value='i'/>
+					<input type='hidden' id='lang' value='<?=$l?>'/>
+				</div> <!-- #w_target -->
+				<div class='entry'>
+					<table id='buttons'>
+						<tr>
+							<td>
+								<input type='text' id='name' placeholder='Tu nombre...'/>
+							</td>
+							<td>
+								<input type='button' id='next' value='Saltar esta' onClick='next();'/>
+							</td>
+							<td>
+								<input type='button' id='save' value='Guardar' onClick='save();'/>
+							</td>
+						</tr>
+					</table>
+				</div>
+			</div> <!-- .section -->
+			<br/><br/><br/>
+			<div class='section' id='w_error'>
+				<h3 class='section_title' id='error_title'></h3>
+				<div class='entry'>
+					<table>
+						<tr>
+							<td>
+								<span id='error_msg'></span>
+								<br/><br/><br/><br/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								<input type='button' value='Cerrar' onClick='closeError();'>
+							</td>
+						</tr>
+					</table>
+				</div>
+			</div>
+		</div> <!-- #content -->
+	</body>
+</html>
+
+<?php
+	}  //if ($l != 'en' && $l != 'en'){  -- ELSE 
+?>

+ 36 - 0
www/traducir/load.php

@@ -0,0 +1,36 @@
+<?php
+	session_start();
+	$http_host = $_SERVER['HTTP_HOST'];
+	include("../functions.php");
+	$proto = getProtocol();
+	$con = startdb('rw');
+	$server = "$proto$http_host";
+
+	// Get parameters
+
+	$t = mysqli_real_escape_string($con, urldecode($_GET['t'])); // table
+	$f = mysqli_real_escape_string($con, urldecode($_GET['f'])); // field (column)
+	$i = mysqli_real_escape_string($con, urldecode($_GET['i'])); // id
+	$c = mysqli_real_escape_string($con, urldecode($_GET['c'])); // content (translation)
+	$l = mysqli_real_escape_string($con, urldecode($_GET['l'])); // language
+	$n = mysqli_real_escape_string($con, urldecode($_GET['n'])); // translator name
+
+	if (strlen($t) == 0 || strlen($f) == 0 || 
+	  is_numeric($i) == false || strlen($c) == 0 || 
+	  ($l != 'en' && $l != 'eu') || strlen($n) == 0){
+		 http_response_code(400); // Bad request
+	}
+	else{
+
+		/*$t = urldecode($_GET['t']); // table
+		$f = urldecode($_GET['f']); // field (column)
+		$i = urldecode($_GET['i']); // id
+		$c = urldecode($_GET['c']); // content (translation)
+		$l = urldecode($_GET['l']); // language
+		$n = urldecode($_GET['n']); // translator name*/
+
+		// TODO: Validate parameters
+		$q_string = "INSERT INTO translation (username, tab, field, eid, lang, text) VALUES ('$n', '$t', '$f', '$i', '$l', '$c');";
+		mysqli_query($con, $q_string);
+	}
+?>

Някои файлове не бяха показани, защото твърде много файлове са промени