Переглянути джерело

Internal site created. Several functionalities implemented for the projects section.

Iñigo Valentin 8 роки тому
батько
коміт
eab26bc07a

+ 2 - 0
.gitignore

@@ -32,3 +32,5 @@ www-admin/.htpasswd
 www/.htaccess_local
 www-admin/.htaccess_local
 
+#3rd party software
+www-admin/script/ckeditor

+ 68 - 0
www-admin/authentication.php

@@ -0,0 +1,68 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (check_session($con)){
+        header("Location: /");
+        exit(-1);
+    }
+    else{
+?>
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta content="text/html; charset=windows-1252" http-equiv="content-type"/>
+        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
+        <link rel='shortcut icon' href='<?=$pserver?>/img/logo/x2/favicon.ico'/>
+        <title>Administration</title>
+        <style>
+<?php
+            include $doc_root . "css/ui.css";
+            include $doc_root . "css/home.css";
+?>
+        </style>
+        <!-- CSS for mobile version -->
+        <style media='(max-width : 990px)'>
+<?php
+            include $doc_root . "css/m/ui.css";
+            include $doc_root . "css/m/home.css";
+?>
+        </style>
+        <!-- Script files -->
+        <script type='text/javascript'>
+<?php
+            include $doc_root . "script/ui.js";
+?>
+        </script>
+    </head>
+    <body>
+        <div class='section' id='authentication'>
+            <h3 class='section_title'>Log In</h3>
+            <div class='entry'>
+                <form method='post' action='/login.php'>
+                    <table>
+                        <tr>
+                            <td>User:</td>
+                            <td><input name="user" type="text"/></td>
+                        </tr>
+                        <tr>
+                            <td>Password:</td>
+                            <td><input name="pass" type="password"/></td>
+                        </tr>
+                        <tr>
+                            <td></td><td><input type="submit" value="Entrar"/></td>
+                        </tr>
+                    </table>
+                </form>
+            </div>
+        </div>
+    </body>
+</html>
+<?php
+    }
+?>

+ 16 - 0
www-admin/blog/delete.php

@@ -0,0 +1,16 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        header("Location: /authentication.php");
+        exit(-1);
+    }
+    else{
+    }
+?>

+ 52 - 0
www-admin/blog/edit.php

@@ -0,0 +1,52 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        header("Location: /authentication.php");
+        exit(-1);
+    }
+    else{
+?>
+<html>
+    <head>
+        <meta content='text/html; charset=windows-1252' http-equiv='content-type'/>
+        <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1'>
+        <link rel='shortcut icon' href='<?=$pserver?>/img/logo/x2/favicon.ico'/>
+        <title>I&ntilde;igo Valentin - Administration Panel</title>
+        <style>
+<?php
+            include $doc_root . "css/ui.css";
+            include $doc_root . "css/home.css";
+?>
+        </style>
+        <!-- CSS for mobile version -->
+        <style media='(max-width : 990px)'>
+<?php
+            include $doc_root . "css/m/ui.css";
+            include $doc_root . "css/m/home.css";
+?>
+        </style>
+        <!-- Script files -->
+        <script type='text/javascript'>
+<?php
+            include $doc_root . "script/ui.js";
+?>
+        </script>
+    </head>
+    <body>
+<?php
+        include $doc_root . "header.php";
+?>
+        <div id='content'>
+        </div> <!-- #content -->
+    </body>
+</html>
+<?php
+    }
+?>

+ 67 - 0
www-admin/blog/index.php

@@ -0,0 +1,67 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        header("Location: /authentication.php");
+        exit(-1);
+    }
+    else{
+?>
+<html>
+    <head>
+        <meta content='text/html; charset=windows-1252' http-equiv='content-type'/>
+        <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1'>
+        <link rel='shortcut icon' href='<?=$pserver?>/img/logo/x2/favicon.ico'/>
+        <title>Blog - I&ntilde;igo Valentin - Administration Panel</title>
+        <style>
+<?php
+            include $doc_root . "css/ui.css";
+            include $doc_root . "css/home.css";
+?>
+        </style>
+        <!-- CSS for mobile version -->
+        <style media='(max-width : 990px)'>
+<?php
+            include $doc_root . "css/m/ui.css";
+            include $doc_root . "css/m/home.css";
+?>
+        </style>
+        <!-- Script files -->
+        <script type='text/javascript'>
+<?php
+            include $doc_root . "script/ui.js";
+?>
+        </script>
+    </head>
+    <body>
+<?php
+        include $doc_root . "header.php";
+?>
+        <div id='content'>
+            <div class='section'>
+                <div class='entry'>
+                    <table>
+                        <tr>
+                            <th>Post</th>
+                            <th>Detalles</th>
+                            <th>Acciones</th>
+                        </tr>
+<?php
+                        // TODO: Chaneg for blog
+                        $q_post = mysqli_query($con, "SELECT project.id, permalink, project_type.title AS type, project.title AS title, project.logo AS logo, header, text, license.id AS license, concat(fname, concat(' ', lname)) AS user, visible, comments, (SELECT version_name FROM project_version v, project_version_type WHERE type = id AND v.project = project.id ORDER BY version_code DESC LIMIT 1) AS version, (SELECT title FROM project_version v, project_version_type WHERE type = id AND v.project = project.id ORDER BY version_code DESC LIMIT 1) AS version_type, (SELECT color FROM project_version v, project_version_type WHERE type = id AND v.project = project.id ORDER BY version_code DESC LIMIT 1) AS version_color, (SELECT image FROM project_image WHERE project = project.id) AS image, (SELECT count(image) FROM project_image WHERE project = project.id) AS image_count FROM project, project_type, license, user WHERE project.type = project_type.id AND project.license = license.id AND project.user = user.id;")
+?>
+                    </table>
+                </div> <!-- .entry -->
+            </div> <!-- .section -->
+        </div> <!-- #content -->
+    </body>
+</html>
+<?php
+    }
+?>

+ 16 - 0
www-admin/blog/new.php

@@ -0,0 +1,16 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        header("Location: /authentication.php");
+        exit(-1);
+    }
+    else{
+    }
+?>

+ 29 - 0
www-admin/css/home.css

@@ -0,0 +1,29 @@
+body{
+    text-align: center;
+}
+
+div#section_table{
+    display: table;
+    width: 100%;
+}
+
+div.section_row{
+    display: table-row;
+}
+
+div.section_cell{
+    display: table-cell;
+    width: 50%;
+}
+
+div.section{
+    display: block;
+    vertical-align: top;
+    text-align: left;
+    margin:  2em;
+}
+
+div.section#authentication{
+    display: inline-block;
+    margin: 8em auto auto auto;
+}

+ 0 - 0
www-admin/css/m/ui.css


+ 55 - 0
www-admin/css/projects.css

@@ -0,0 +1,55 @@
+table#project_list{
+    width: 100%;
+    border-spacing: 0;
+    border-collapse: collapse;
+}
+
+table#project_list th{
+    font-weight: bold;
+    background: linear-gradient(to bottom, #4e9987 0%,#69d8b9 89%,#60caac 97%,#ade8f9 100%);
+    border: 0.1em solid #335533;
+}
+
+table#project_list td{
+    border: 0.1em solid #335533;
+    padding: 0.2em;
+}
+
+table#project_list td.td_project{
+    width: 30%;
+}
+
+table#project_list td.td_project h4{
+    margin: 0.2em;
+}
+
+table#project_list td.td_project h4 img{
+    max-height: 2em;
+    max-width: 2em;
+    vertical-align: middle;
+}
+
+table#project_list td.td_project img.project_image{
+    border: 0.2em solid #335533;
+    border-radius: 0.4em;
+    max-height: 3em;
+    max-width: 3em;
+}
+
+table#project_list td.td_details{
+    width: 50%;
+    font-size: 80%;
+}
+
+table#project_list td.td_actions{
+    width: 20%;
+    text-align: center;
+}
+
+table#project_list td.td_actions input{
+    padding: 0.1em;
+    display: block;
+    margin: auto;
+    width: 90%;
+}
+

+ 472 - 0
www-admin/css/ui.css

@@ -0,0 +1,472 @@
+/**********************************
+ * Fonts used across the page     *
+ **********************************/
+
+/* Font */
+@font-face {
+    font-family: 'Nunito'; 
+    src: url('/fonts/Nunito-Regular.ttf'); 
+}
+
+/**********************************
+ * Styles to be applied across    *
+ * all the site for all the       *
+ * elements of it's type          *
+ **********************************/
+
+/* Styles for the body of the page */
+body{
+    background-color: #111111;
+}
+
+/* Style for all links */
+a{
+    color: #555555;
+    text-shadow: 0 0 0.5em #7777ff;
+    text-decoration: none;
+}
+
+/* Elements fith bold font */
+.bold{
+    font-weight: bold;
+}
+
+.pointer {
+    cursor: pointer;
+}
+
+/* Hidden elements */
+.hidden{
+    display: none;
+}
+
+img.slider{
+    width: 1em;
+    height: 1em;
+    vertial-align: middle;
+    transition: all .3s ease-in-out;
+}
+
+div#cover{
+    display: none;
+    background-color: #000000bb;
+    opacity: 0;
+    transition: opacity .3s ease-in-out;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
+div#dialog{
+    display: none;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    opacity: 0;
+    transition: opacity .3s ease-in-out;
+    text-align: center;
+    z-index: 1;
+}
+
+div#dialog div#dialog_background{
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: #00000088;
+    z-index: -1;
+}
+
+div#dialog div.section{
+    width: 50%;
+    height: 50%;
+    margin: 5em auto auto auto;
+    z-index: 1;
+}
+
+
+/**********************************
+ * Header style                  *
+ **********************************/
+
+div#header{
+    background-color: #000000;
+    margin: 0;
+    width: 100%;
+    height: 2em;
+    padding: 0;
+}
+
+div#header img{
+    height: 1.6em;
+    vertical-align: center;
+}
+
+div#header table{
+    width: 100%;
+    height: 100%;
+    margin-left: auto;
+    margin-right: auto;
+    border-spacing: 0;
+    border-collapse: collapse;
+    margin: 0;
+    table-layout: fixed;
+}
+
+div#header td{
+    color: #dddddd;
+    font-weight: bold;
+    text-align: center;
+}
+
+div#header td a{
+    color: #dddddd;
+    font-weight: bold;
+    text-align: center;
+    text-shadow: none;
+    text-decoration: none;
+    transition: all .3s ease-in-out;
+}
+
+
+/******************************************
+ * Secondary header.                     *
+ ******************************************/
+div.secondary_header{
+    background-color: #333333;
+    margin: 0;
+    display: none;
+    width: 100%;
+    height: 2em;
+}
+
+div.secondary_header table{
+    width: 90%;
+    margin-left: auto;
+    margin-right: auto;
+    table-layout: fixed;
+}
+
+div.secondary_header td{
+    text-align: center;
+}
+
+div.secondary_header td a{
+    color: #dddddd;
+    font-weight: bold;
+    text-align: center;
+    text-shadow: none;
+    text-decoration: none;
+    transition: all .3s ease-in-out;
+}
+
+div.secondary_header td a:hover{
+    color: #dddddd;
+    text-shadow: none;
+    text-decoration: none;
+}
+
+
+/**********************************
+ * Styles for the elements that   *
+ * compose the basic strucure of  *
+ * the site.                      *
+ **********************************/
+
+/* The content is everything between the header and the footer */
+div#content{
+    position: relative;
+    width: 100%;
+    height: 100%;
+    margin-bottom: 1.875em;
+}
+
+div.section{
+    margin: 0.5em;
+    padding: 0;
+    background-color: #ffffff;
+    border: 0.063em solid #005500;
+    border-radius: 1em 1em;
+    box-shadow: 0 0 0.75em #003300;
+    overflow: hidden;
+}
+
+div.section h3.section_title{
+    font-weight: bold;
+    color: #ccddff;
+    text_align: left;
+    padding: 0.2em 0.4em 0.2em 0.4em;
+    margin: 0;
+    text-shadow: 0 0 0.4em #000022;
+    font-size: 150%;
+    background: linear-gradient(to bottom, #1e9957 0%,#29d889 89%,#20ca7c 97%,#7de8b9 100%);
+}
+
+/* .entry is a style only class to show content. Must be allways children os a .lighted element */
+div.section div.entry{
+    border: 0.1em solid #aaffaa00;
+    border-radius: 0.3em;
+    padding: 0.5em;
+    margin: 0.5em;
+    transition: all .4s ease-in-out;
+}
+
+div.section div.entry_list:hover{
+    background-color: #efffef;
+    border: 0.1em solid #aaffaaff;
+}
+
+
+
+/* Style for the mathces in search results */
+span.result_counter{
+    margin-left: 1.2em;
+    margin-bottom: 0.5em;
+    font-weight: bold;
+    font-style: italic;
+}
+
+/* Shown when no records on database */
+div.unavailable{
+    margin-left: 4em;
+    font-style: italic;
+}
+
+
+/**********************************
+ * Styles to be applied to some   *
+ * horizontally scrollable        *
+ * elements                       *
+ **********************************/
+
+/* Horizontall scrollbar that apears when a project has lots of renders */
+.slider::-webkit-scrollbar{
+    width: 0.5em;
+    height: 0.25em;
+    background-color: #444444;
+} 
+.slider::-webkit-scrollbar-thumb{
+    background-color: #cccccc;
+    border-radius: 0.714em;
+}
+.slider::-webkit-scrollbar-thumb:hover{
+    background-color: #cccccc;
+    border: 0.143em solid #000000;
+}
+.slider::-webkit-scrollbar-thumb:active{
+    background-color: #cccccc;
+    border: 0.143em solid #000000;
+}
+
+/* Icons for sharing page in a social network */
+img.social_icon{
+    width: 4.286em;
+    height: 4.286em;
+}
+
+/* Elements that should have the cursor as pointer */
+.pointer{
+    cursor: pointer;
+}
+
+
+
+/**********************************
+ * Styles for diverse input       *
+ * elements. Type-assigned        *
+ **********************************/
+
+/* Font for all the input elements */
+input{
+    font-family: 'Nunito';
+}
+
+/* Style forr buttons */
+input[type=button], input[type=submit]{
+    font-weight: bold;
+    color: #cccccc;
+    background-color: #555555;
+    border: 0.143em solid #bbbbbb;
+    border-radius: 0.429em;
+    padding: 0.5em;
+    text-shadow: 0 0 0.75em #000000;
+    cursor: pointer;
+}
+
+/* Style for textboxes */
+input[type=text], input[type=password]{
+    font-weight: bold;
+    color: #224422;
+    background-color: #bbccbb;
+    border: 0.286em solid #ddeedd; 
+    border-color: #dddddd;
+    border-radius: 0.429em;
+    padding: 0.25em;
+    text-shadow: 0 0 0.5em #ffffff;
+}
+
+input[type=checkbox]{
+    width: 1em;
+    height: 1em;
+    border-radius: 0.2em;
+    border: 0.063em solid #005500;
+}
+
+/* Style for textareas */
+textarea{
+    width: 80%;
+    font-weight: bold;
+    color: #444444;
+    background-color: #bbbbbb;
+    border: 0.286em solid #dddddd; 
+    border-color: #dddddd;
+    border-radius: 0.286em;
+    padding: 0.25em;
+    text-shadow: 0 0 0.5em #ffffff;
+    resize: none;
+}
+
+/* Style for selects */
+select{
+    font-weight: bold;
+    color: #444444;
+    background-color: #bbbbbb;
+    border: 0.286em solid #dddddd; 
+    border-radius: 0.286em;
+    padding: 0.25em;
+    text-shadow: 0 0 0.5em #ffffff;
+}
+
+/* Style for placeholders in input fields */
+::-webkit-input-placeholder { /* WebKit browsers */
+    color: #777777;
+}
+:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
+    color: #777777;
+}
+::-moz-placeholder { /* Mozilla Firefox 19+ */
+    color: #777777;
+}
+:-ms-input-placeholder { /* Internet Explorer 10+ */
+    color: #777777;
+}
+
+/* Style-only class user to indicate that a field is incorrect. Ususally this class is added to an element with js */
+.error{
+    border-color: #ffaaaa;
+}
+
+/* Style for the textbox input when the entered text is not the expected one */
+input[type=text].error, input[type=password].error{
+    border-color: #ffaaaa;
+}
+
+/* Style for the textared input when the entered text is not the expected one */
+textarea.error{
+    border-color: #ffaaaa;
+}
+
+/* Style for buttons that act as links */
+a.a_button{
+    display: inline-block;
+    color: #cccccc;
+    background-color: #555555;
+    border: 0.143em solid #bbbbbb;
+    border-radius: 0.429em;
+    padding: 0.5em;
+    text-shadow: 0 0 0.75em #000000;
+    text-decoration: none;
+    font: -webkit-small-control;
+    font-family: 'Nunito';
+    font-weight: bold;
+}
+
+
+
+/**********************************
+ * Styles for editable items  .   *
+ * horizontally scrollable        *
+ * elements                       *
+ **********************************/
+
+/* Field value, not editing */
+.editable .field_result{
+    display: initial;
+}
+
+/* Button to start editing*/
+.editable .button_edit{
+    display: initial;
+    cursor: pointer;
+    max-width: 1.2em;
+    vertical-align: middle;
+}
+
+/* Field value, editing. */
+.editable .field_editable{
+    display: none;
+}
+
+/* Field value, editing, textarea <-> cke */
+.editable .cke{
+    display: none;
+}
+
+/* Button to save edition. */
+.editable .button_save{
+    display: none;
+    cursor: pointer;
+    max-width: 1.2em;
+    vertical-align: middle;
+}
+
+/* Button to save edition. */
+.editable .button_cancel{
+    display: none;
+    cursor: pointer;
+    max-width: 1.2em;
+    vertical-align: middle;
+}
+
+/******************************************
+* Language selectors                      *
+******************************************/
+
+div#lang_tabs{
+    margin-top: 2em;
+    margin-bottom: 2em;
+}
+
+div#lang_tabs table{
+    width: 100%;
+}
+
+div#lang_tabs td{
+    color: #555555;
+    font-weight: bold;
+    width: 33%;
+    border: 0.1em solid black;
+    margin: 0;
+}
+
+div#lang_tabs td.lang_tabs_active{
+    color: #0078ff;
+    border-bottom: 0.1em solid #ffffff;
+}
+
+div.content_lang{
+    display: none;
+}
+
+div.content_lang_active{
+    display: initial;
+}

BIN
www-admin/fonts/Nunito-Bold.ttf


BIN
www-admin/fonts/Nunito-Light.ttf


BIN
www-admin/fonts/Nunito-Regular.ttf


+ 93 - 0
www-admin/fonts/OFL.txt

@@ -0,0 +1,93 @@
+Copyright (c) 2011, Vernon Adams (vern@newtypography.co.uk),
+with Reserved Font Name Nunito.
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

+ 354 - 0
www-admin/functions.php

@@ -0,0 +1,354 @@
+<?php
+
+    $IMG_SIZE_PREVIEW = 600;
+    $IMG_SIZE_MINIATURE = 200;
+
+
+    /*****************************************************
+     * 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 start_db(){
+        //Include the db configuration file. It's somehow like this
+        /*
+        <?php
+            $db_host = "XXXX";
+            $db_name = "XXXX";
+            $db_user = "XXXX";
+            $db_pass = "XXXX";
+        ?>
+        */
+        include ".htpasswd";
+
+        $con = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
+
+        // Check connection
+        if (mysqli_connect_errno()){
+            error_log("Failed to connect to database: " . mysqli_connect_error());
+            return -1;
+        }
+
+        //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;
+    }
+
+
+    /*****************************************************
+     * Finds out the protocol the user is connecting to  *
+     * the site with (http or https)                     *
+     * @return: (string): "http://" or "https://".       *
+     ****************************************************/
+    function get_protocol(){
+        if (isset($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] == "on" || $_SERVER["HTTPS"] == 1) || isset($_SERVER["HTTP_X_FORWARDED_PROTO"]) && $_SERVER["HTTP_X_FORWARDED_PROTO"] == "https") {
+            $protocol = "https://";
+        }
+        else {
+            $protocol = "http://";
+        }
+        return $protocol;
+    }
+
+
+    /****************************************************
+    * This function turns a date string into a human    *
+    * readable string, deppending o the specified       *
+    * language.                                         *
+    * @params:                                          *
+    *    strdate: (string): Date string.                *
+    *    lang: (string): Language code (es, en, eu).    *
+    *    http_accept_language: (string) Raw header with *
+    *                          info about client        *
+    *                          language preferences.    *
+    *    time: (boolean): Append the time at the end.   *
+    * @return: (string array) List of the languages     *
+    *          offered, sorted by prefference.          *
+    ****************************************************/
+    function format_date($strdate, $lang, $time = true){
+        $date = strtotime($strdate);
+        $year = date('o', $date);
+        $month = date('n', $date);
+        $month --;
+        $day = date('j', $date);
+        $wday = date('N', $date);
+        $wday --;
+        $hour = date('H', $date);
+        $minute = date('i', $date);
+        switch ($lang){
+            case 'en':
+                $week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
+                $months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
+                if ($time){
+                    $str = "$week[$wday], $months[$month] $day, $year at $hour:$minute";
+                }
+                else{
+                    $str = "$week[$wday], $months[$month] $day, $year";
+                }
+                break;
+            case 'eu':
+                $week = ['astelehena', 'asteartea', 'asteazkena', 'osteguna', 'ostirala', 'larumbata', 'igandea'];
+                $months = ['urtarrilaren', 'otsailaren', 'martxoaren', 'apirilaren', 'maiatzaren', 'ekainaren', 'uztailaren', 'abuztuaren', 'irailaren', 'urriaren', 'azaroaren', 'abenduaren'];
+                if ($time){
+                    $str = $year . "ko $months[$month] $day" . "an, $week[$wday], $hour:$minute";
+                }
+                else{
+                    $str = $year . "ko $months[$month] $day" . "an, $week[$wday]";
+                }
+                break;
+            default:
+                $week = ['Lunes', 'Martes', 'Mi&eacute;rcoles', 'Jueves', 'Viernes', 'S&aacute;bado', 'Domingo'];
+                $months = ['enero', ' febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'];
+                if ($time){
+                    $str = "$week[$wday] $day de $months[$month] de $year a las $hour:$minute";
+                }
+                else{
+                    $str = "$week[$wday] $day de $months[$month] de $year";
+                }
+        }
+        return $str;
+    }
+
+
+    /*****************************************************
+     * Generates a URL-valid string from a regular one.  *
+     *                                                   *
+     * @params:                                          *
+     *    text: (string): Original string.               *
+     * @return: (string): URL-valid string.              *
+     *****************************************************/
+    function permalink($text){
+        $unwanted_array = array("Š"=>"S", "š"=>"s", "Ž"=>"Z", "ž"=>"z", "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"A", "Ç"=>"C", "È"=>"E", "É"=>"E",
+                            "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I", "Î"=>"I", "Ï"=>"I", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O", "Õ"=>"O", "Ö"=>"O", "Ø"=>"O", "Ù"=>"U",
+                            "Ú"=>"U", "Û"=>"U", "Ü"=>"U", "Ý"=>"Y", "Þ"=>"B", "ß"=>"Ss", "à"=>"a", "á"=>"a", "â"=>"a", "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"a", "ç"=>"c",
+                            "è"=>"e", "é"=>"e", "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", "ï"=>"i", "ð"=>"o", "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o",
+                            "ö"=>"o", "ø"=>"o", "ù"=>"u", "ú"=>"u", "û"=>"u", "ý"=>"y", "þ"=>"b", "ÿ"=>"y" );
+        $str = strtr( $text, $unwanted_array );
+        $str = preg_replace("/[^\da-zA-Z ]/i", "", $str);
+        $str = str_replace(" ", "-", $str);
+        return $str;
+    }
+
+
+    /*****************************************************
+     * Retrieves a text fragment from the database.      *
+     *                                                   *
+     * @params:                                          *
+     *    con (Mysql connection): Connection handler.    *
+     *    id: (string): Text identifier.                 *
+     *    lang: (string): Language identifier.           *
+     * @return: (string): Text.                          *
+     *****************************************************/
+    function text($con, $id, $lang){
+        $q = mysqli_query($con, "SELECT text, file FROM text WHERE id = '$id' AND lang = '$lang';");
+        $r = mysqli_fetch_array($q);
+        if (strlen($r["file"]) > 0){
+            return file_get_contents($_SERVER["DOCUMENT_ROOT"] . "string/" . $r["file"]);
+        }
+        else{
+            return $r["text"];
+        }
+    }
+
+
+    /*****************************************************
+     * This function closes all the opened HTML tags in  *
+     * a given string.                                   *
+     *                                                   *
+     * @params:                                          *
+     *    html: (string): The string with HTML tags.     *
+     * @return: (string): HTML with closed tags.         *
+     *****************************************************/
+    function close_tags($html) {
+        preg_match_all("#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU", $html, $result);
+        $openedtags = $result[1];
+        preg_match_all("#</([a-z]+)>#iU", $html, $result);
+        $closedtags = $result[1];
+        $len_opened = count($openedtags);
+        if (count($closedtags) == $len_opened) {
+            return $html;
+        }
+        $openedtags = array_reverse($openedtags);
+        for ($i=0; $i < $len_opened; $i++) {
+            if (!in_array($openedtags[$i], $closedtags)) {
+                $html .= "</".$openedtags[$i].">";
+            } else {
+                unset($closedtags[array_search($openedtags[$i], $closedtags)]);
+            }
+        }
+        return $html;
+    }
+
+
+
+    /*****************************************************
+     * Text shortener. Given a string, it trims in the   *
+     * proximity of the desired string, ut to the next   *
+     * white character. If indicated, it will append a   *
+     * link to the full text.                            *
+     *                                                   *
+     * @params:                                          *
+     *    text: (string): The text to shorten.           *
+     *    length: (int): The desired length.             *
+     *    linktext: (string): Text fot the link.         *
+     *    link: (string): URI of the full text.          *
+     * @return: (string): Cutted text.                   *
+     *****************************************************/
+     function cut_text($text, $length, $linktext, $link){
+        if (strlen($text) < $length){
+            return $text;
+        }
+        $cut = substr($text, 0, strpos($text, " ", $length));
+        $cut = closeTags($cut);
+        if (strlen($cut) == 0){
+            $cut = $text;
+        }
+        if (strlen($text) != strlen($cut)){
+            $cut = $cut . "... <a href='$link'>$linktext</a>";
+        }
+        return $cut;
+    }
+
+
+    /*****************************************************
+     * Finds out the IP address of the client.           *
+     *                                                   *
+     * @return: (String): Client IP address.             *
+     *****************************************************/
+    function get_ip(){
+        $client  = @$_SERVER["HTTP_CLIENT_IP"];
+        $forward = @$_SERVER["HTTP_X_FORWARDED_FOR"];
+        $remote  = $_SERVER["REMOTE_ADDR"];
+        if(filter_var($client, FILTER_VALIDATE_IP)){
+            $ip = $client;
+        }
+        elseif(filter_var($forward, FILTER_VALIDATE_IP)){
+            $ip = $forward;
+        }
+        else{
+            $ip = $remote;
+        }
+        return $ip;
+    }
+
+
+    /*****************************************************
+     * Tries to login a user to the internal page.       *
+     *                                                   *
+     * @params:                                          *
+     *    con (Mysql connection): Connection handler.    *
+     *    user (string): Username, plain text.           *
+     *    pass (string): Password SHA-1 sum.             *
+     * @return: (boolean): True if user pass/match,      *
+     *          false otherwise.                         *
+     *****************************************************/
+    function login($con, $user, $pass){
+        session_start();
+        $q = mysqli_query($con,"SELECT id, salt, username AS username, sha1(salt) AS s FROM user WHERE (lower(username) = lower('$user') OR lower(email) = lower('$user')) AND password = sha1(concat('$pass', sha1(salt)));");
+        if (mysqli_num_rows($q) == 1){
+            $r = mysqli_fetch_array($q);
+            $_SESSION['id'] = $r['id'];
+            $_SESSION['salt'] = $r['s'];
+            $_SESSION['name'] = $r['username'];
+            return true;
+        }
+        else{
+            error_log("Invalid login. username = $user, id = $r[id];");
+            return false;
+        }
+    }
+
+
+    /*****************************************************
+     * Checks if a user is logged in.                    *
+     *                                                   *
+     * @params:                                          *
+     *    con (Mysql connection): Connection handler.    *
+     * @return: (boolean): True if the user is signed    *
+     *          in, false otherwise.                     *
+     *****************************************************/
+    function check_session($con){
+        session_start(['cookie_lifetime' => 1800,]);
+        $qr = mysqli_query($con, "SELECT id FROM user WHERE id = '$_SESSION[id]' AND sha1(salt) = '$_SESSION[salt]';");
+        //error_log("SELECT id FROM user WHERE id = '$_SESSION[id]' AND md5(salt) = '$_SESSION[salt]';");
+        if (mysqli_num_rows($qr) == 1)
+            return true;
+        else{
+            return false;
+            error_log("Invalid session. username = $_SESSION[name], id = $_SESSION[id]");
+        }
+    }
+
+
+    /*****************************************************
+     * Performs an update in the database.               *
+     *                                                   *
+     * @params:                                          *
+     *    con (Mysql connection): Connection handler.    *
+     *    s_table (string): Table name.                  *
+     *    s_column (string): Column name.                *
+     *    type (string): Column type (VARCHAR, NUMBER,   *
+     *         DATE or TIME. If the value to insert in   *
+     *         null, type must be NULL).                 *
+     *    s_value (string): New value. Ignoered if type  *
+     *            is NULL.                               *
+     *    id (string): Row id. If the table doesn't have *
+     *       a column named 'id', this can't be used.    *
+     *****************************************************/
+    function db_update($con, $s_table, $s_column, $type, $s_value, $id){
+        $table = mysqli_real_escape_string($con, $s_table);
+        $column = mysqli_real_escape_string($con, $s_column);
+        switch (strtoupper($type)){
+            case "NULL":
+                $value = "null";
+                break;
+            case "VARCHAR":
+                $value = "'" . mysqli_real_escape_string($con, $s_value) . "'";
+                break;
+            case "NUMBER":
+                $value = intval(mysqli_real_escape_string($con, $s_value));
+                break;
+            case "DATE":
+                if (!preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) \d{2}:\d{2}:\d{2}$/",$s_value)){
+                    return -2;
+                }
+                $value = "str_to_date('$s_value', '%Y-%m-%d')";
+                break;
+            case "TIME":
+                if (!preg_match("^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$",$s_value)){
+                    return -2;
+                }
+                $value = "str_to_date('$s_value', '%Y-%m-%d %H:%i:%s')";
+                break;
+            default:
+                return -1;
+        }
+        $q = mysqli_query($con, "UPDATE $table SET $column = $value WHERE id = $id;");
+        return 0;
+    }
+
+
+    /*****************************************************
+     * Performs a delete                .                *
+     *                                                   *
+     * @params:                                          *
+     *    con (Mysql connection): Connection handler.    *
+     *    s_table (string): Table name.                  *
+     *    id (string): Row id. If the table doesn't have *
+     *       a column named 'id', this can't be used.    *
+     *****************************************************/
+    function db_delete($con, $s_table, $id){
+        $table = mysqli_real_escape_string($con, $s_table);
+        $q = mysqli_query($con, "DELETE FROM $table WHERE id = $id;");
+        return 0;
+    }
+?>

+ 37 - 0
www-admin/functions/save.php

@@ -0,0 +1,37 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        http_response_code(401);
+        header("Location: /authentication.php");
+    }
+    else{
+        $table = mysqli_real_escape_string($con, $_GET["t"]);
+        $column = mysqli_real_escape_string($con, $_GET["c"]);
+        $value = htmlspecialchars_decode(mysqli_real_escape_string($con, $_GET["v"]));
+        $id = mysqli_real_escape_string($con, $_GET["i"]);
+        // TODO: Validation!
+        if ($table == 'text'){
+            if (mysqli_query($con, "UPDATE text SET text = '$value' WHERE id = '$id' AND lang = '$column';")){
+                http_response_code(200); // OK.
+            }
+            else{
+                http_response_code(500); // Generic internal error.
+            }
+        }
+        else{
+            if (mysqli_query($con, "UPDATE $table SET $column = '$value' WHERE id = $id;")){
+                http_response_code(200); // OK.
+            }
+            else{
+                http_response_code(500); // Generic internal error.
+            }
+        }
+    }
+?>

+ 87 - 0
www-admin/header.php

@@ -0,0 +1,87 @@
+<div id='dialog'>
+    <div id='dialog_background'>
+    </div>
+    <div class='section'>
+        <h3 id='dialog_title' class='section_title'></h3>
+        <div class='entry'>
+            <p id='dialog_text'></p>
+            <div id='dialog_button_a_container'>
+                <input type='button' id='dialog_accept' value='Aceptar'/>
+            </div>
+            <div id='dialog_button_yn_container'>
+                <input type='button' id='dialog_yes' value='Yes'/>
+                <input type='button' id='dialog_no' value='No'/>
+            </div>
+        </div> <!-- .entry -->
+    </div> <!-- .section -->
+</div>
+<div id='header'>
+    <table>
+        <tr>
+            <td>
+                <img src='<?=$server?>/img/misc/logo.png'/>
+                <span style='font-weight:normal;font-style:italic;font-size:90%;'><?=$_SESSION['name']?></span>
+            </td>
+            <td>
+                <a href='<?=$server?>/' class='pointer header_section'>Inicio</a>
+            </td>
+            <td class='pointer header_section' onClick='showHeader("blog", this);'>
+                <span class='pointer'>Blog</span>
+            </td>
+            <td class='pointer header_section' onClick='showHeader("projects", this);'>
+                <span class='pointer'>Projects</span>
+            </td>
+            <td class='pointer header_section' onClick='showHeader("stats", this);'>
+                <span class='pointer'>Stats</span>
+            </td>
+            <td class='pointer header_section' onClick='showHeader("settings", this);'>
+                <span class='pointer'>Settings</span>
+            </td>
+        </tr>
+    </table>
+</div>
+<div class='secondary_header' id='header_blog'>
+    <table>
+        <tr>
+            <td>
+                <a href='<?=$server?>/blog/add/'>New post</a>
+            </td>
+            <td>
+                <a href='<?=$server?>/blog/'>Manage posts</a>
+            </td>
+        </tr>
+    </table>
+</div>
+<div class='secondary_header' id='header_projects'>
+    <table>
+        <tr>
+            <td>
+                <a href='<?=$server?>/projects/add/'>New project</a>
+            </td>
+            <td>
+                <a href='<?=$server?>/projects/'>Manage projects</a>
+            </td>
+        </tr>
+    </table>
+</div>
+<div class='secondary_header' id='header_stats'>
+    <table>
+        <tr>
+            <td>
+                <a href='<?=$server?>/stats/'>View stats</a>
+            </td>
+        </tr>
+    </table>
+</div>
+<div class='secondary_header' id='header_settings'>
+    <table>
+        <tr>
+            <td>
+                <a href='<?=$server?>/settings/'>Page settings</a>
+            </td>
+            <td>
+                <a href='<?=$server?>/settings/profile.php'>Profile settings</a>
+            </td>
+        </tr>
+    </table>
+</div>

BIN
www-admin/img/icon/cancel.png


BIN
www-admin/img/icon/edit.png


BIN
www-admin/img/icon/save.png


+ 101 - 0
www-admin/index.php

@@ -0,0 +1,101 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        header("Location: /authentication.php");
+        exit(-1);
+    }
+    else{
+?>
+<html>
+    <head>
+        <meta content='text/html; charset=windows-1252' http-equiv='content-type'/>
+        <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1'>
+        <link rel='shortcut icon' href='<?=$pserver?>/img/logo/x2/favicon.ico'/>
+        <title>I&ntilde;igo Valentin - Administration Panel</title>
+        <style>
+<?php
+            include $doc_root . "css/ui.css";
+            include $doc_root . "css/home.css";
+?>
+        </style>
+        <!-- CSS for mobile version -->
+        <style media='(max-width : 990px)'>
+<?php
+            include $doc_root . "css/m/ui.css";
+            include $doc_root . "css/m/home.css";
+?>
+        </style>
+        <!-- Script files -->
+        <script type='text/javascript'>
+<?php
+            include $doc_root . "script/ui.js";
+?>
+        </script>
+    </head>
+    <body>
+<?php
+        include $doc_root . "header.php";
+?>
+        <div id='content'>
+            <div id='section_table'>
+                <div class='section_row'>
+                    <div class='section_cell'>
+                        <div class='section'>
+                            <h3 class='section_title'>Blog</h3>
+                            <div class='entry'>
+                                <ul>
+                                    <li><a href='<?=$server?>/blog/add/'>New post</a></li>
+                                    <li><a href='<?=$server?>/blog/'>Manage posts</a></li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                    <div class='section_cell'>
+                        <div class='section'>
+                            <h3 class='section_title'>Projects</h3>
+                            <div class='entry'>
+                                <ul>
+                                    <li><a href='<?=$server?>/projects/add/'>New project</a></li>
+                                    <li><a href='<?=$server?>/projects/'>Manage projects</a></li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </div> <!-- .section_row -->
+                <div class='section_row'>
+                    <div class='section_cell'>
+                        <div class='section'>
+                            <h3 class='section_title'>Stats</h3>
+                            <div class='entry'>
+                                <ul>
+                                    <li><a href='<?=$server?>/stats/'>View stats</a></li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                    <div class='section_cell'>
+                        <div class='section'>
+                            <h3 class='section_title'>Settings</h3>
+                            <div class='entry'>
+                                <ul>
+                                    <li><a href='<?=$server?>/settings/'>Page settings</a></li>
+                                    <li><a href='<?=$server?>/settings/profile.php'>Profile settings</a></li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </div> <!-- .section_row -->
+            </div> <!-- #section_table -->
+        </div> <!-- #content -->
+    </body>
+</html>
+<?php
+    }
+?>

+ 14 - 0
www-admin/login.php

@@ -0,0 +1,14 @@
+<?php
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $con = start_db();
+    $user = mysqli_real_escape_string($con, $_POST["user"]);
+    $pass = mysqli_real_escape_string($con, $_POST["pass"]);
+    $pass = sha1($pass);
+    if (login($con, $user, $pass)){
+        header("Location: /index.php");
+    }
+    else{
+        header("Location: /authentication.php");
+    }
+?>

+ 33 - 0
www-admin/projects/delete.php

@@ -0,0 +1,33 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        http_response_code(401); // Not logged in: Forbidden.
+    }
+    else{
+        $id = intval(mysqli_real_escape_string($con, $_GET["p"]));
+        if (strlen($id) < 1){
+            http_response_code(400); // No or bad ID: Bad request.
+        }
+        else{
+            if (mysqli_num_rows(mysqli_query($con, "SELECT id FROM project WHERE id = $id;")) == 0){
+                http_response_code(404); // Unexistent id: Not found.
+            }
+            else{
+                mysqli_query($con, "DELETE FROM project_version WHERE project = $id;");
+                mysqli_query($con, "DELETE FROM project_url WHERE project = $id;");
+                mysqli_query($con, "DELETE FROM project_tag WHERE project = $id;");
+                mysqli_query($con, "DELETE FROM project_image WHERE project = $id;");
+                mysqli_query($con, "DELETE FROM project_comment WHERE project = $id;");
+                mysqli_query($con, "DELETE FROM project WHERE id = $id;");
+                http_response_code(200); //OK.
+            }
+        }
+    }
+?>

+ 145 - 0
www-admin/projects/edit.php

@@ -0,0 +1,145 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $lang = "es";
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = $proto . substr($http_host, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        http_response_code(401);
+        header("Location: /authentication.php");
+    }
+    else{
+        $id = intval(mysqli_real_escape_string($con, $_GET["p"]));
+        if (strlen($id) < 1){
+            http_response_code(400); // No or bad ID: Bad request.
+            header("Location: /projects/");
+        }
+        else{
+            $q_project = mysqli_query($con, "SELECT * FROM project WHERE id = $id;");
+            if (mysqli_num_rows($q_project) == 0){
+                http_response_code(404); // Unexistent id: Not found.
+                header("Location: /projects/");
+            }
+            else{
+                $r_project = mysqli_fetch_array($q_project);
+                $id = $r_project["id"];
+                $title = text($con, $r_project["title"], $lang);
+                $q_lang = mysqli_query($con, "SELECT * FROM lang;");
+?>
+<html>
+    <head>
+        <meta content='text/html; charset=windows-1252' http-equiv='content-type'/>
+        <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1'>
+        <link rel='shortcut icon' href='<?=$pserver?>/img/logo/x2/favicon.ico'/>
+        <title><?=$title?>I&ntilde;igo Valentin - Administration Panel</title>
+        <style>
+<?php
+            include $doc_root . "css/ui.css";
+            include $doc_root . "css/home.css";
+?>
+        </style>
+        <!-- CSS for mobile version -->
+        <style media='(max-width : 990px)'>
+<?php
+            include $doc_root . "css/m/ui.css";
+            include $doc_root . "css/m/home.css";
+?>
+        </style>
+        <!-- Script files -->
+        <script type='text/javascript'>
+<?php
+            include $doc_root . "script/ui.js";
+?>
+        </script>
+         <script src='/script/ckeditor/ckeditor.js'></script>
+    </head>
+    <body>
+<?php
+        include $doc_root . "header.php";
+?>
+        <div id='content'>
+            <div class='section'>
+                <h3 class='section_title'><?=$title?></h3>
+                <div class='entry'>
+                    <span class='bold'>URL:</span>
+                    <?=$pserver?>/
+                    <span class='editable'>
+                        <span class='field_result'><?=$r_project["permalink"]?></span>
+                        <img class='button_edit' src='<?=$server?>/img/icon/edit.png' onclick='enableEdit(this);'/>
+                        <input class='field_editable' type='text' value='<?=$r_project["permalink"]?>'/>
+                        <img class='button_save' src='<?=$server?>/img/icon/save.png' onclick='saveEdit(this, "project", "permalink", <?=$id?>);'/>
+                        <img class='button_cancel' src='<?=$server?>/img/icon/cancel.png' onclick='cancelEdit(this);'/>
+                    </span>
+                    <div id='lang_tabs'>
+                        <table>
+                            <tr>
+<?php
+                                mysqli_data_seek($q_lang, 0);
+                                $active = 'lang_tabs_active';
+                                while ($r_lang = mysqli_fetch_array($q_lang)){
+?>
+                                    <td class='pointer <?=$active?>' id='lang_tab_<?=$r_lang["code"]?>' onclick='showLanguage("<?=$r_lang["code"]?>");'>
+                                        <?=$r_lang["name"]?>
+                                    </td>
+<?php
+                                    $active = '';
+                                }
+?>
+                            </tr>
+                        </table>
+                    </div>
+<?php
+                    mysqli_data_seek($q_lang, 0);
+                    $active = 'content_lang_active';
+                    while ($r_lang = mysqli_fetch_array($q_lang)){
+?>
+                        <div id='content_lang_<?=$r_lang["code"]?>' class='content_lang <?=$active?>'>
+                            <div class='editable'>
+                                Title:
+                                <span class='field_result'><?=text($con, $r_project["title"], $r_lang["code"])?></span>
+                                <img class='button_edit' src='<?=$server?>/img/icon/edit.png' onclick='enableEdit(this);'/>
+                                <input class='field_editable' type='text' value='<?=text($con, $r_project["title"], $r_lang["code"])?>'/>
+                                <img class='button_save' src='<?=$server?>/img/icon/save.png' onclick='saveEdit(this, "text", "<?=$r_lang["code"]?>", "<?=$r_project["title"]?>");'/>
+                                <img class='button_cancel' src='<?=$server?>/img/icon/cancel.png' onclick='cancelEdit(this);'/>
+                            </div>
+                            <hr/>
+                            <div class='editable'>
+                                Summary: 
+                                <span class='field_result'><?=text($con, $r_project["summary"], $r_lang["code"])?></span>
+                                <img class='button_edit' src='<?=$server?>/img/icon/edit.png' onclick='enableEdit(this);'/>
+                                <input class='field_editable' type='text' value='<?=text($con, $r_project["summary"], $r_lang["code"])?>'/>
+                                <img class='button_save' src='<?=$server?>/img/icon/save.png' onclick='saveEdit(this, "text", "<?=$r_lang["code"]?>", "<?=$r_project["summary"]?>");'/>
+                                <img class='button_cancel' src='<?=$server?>/img/icon/cancel.png' onclick='cancelEdit(this);'/>
+                            </div>
+                            <hr/>
+                            <div class='editable'>
+                                Text:
+                                <img class='button_edit' src='<?=$server?>/img/icon/edit.png' onclick='enableEdit(this);'/>
+                                <img class='button_save' src='<?=$server?>/img/icon/save.png' onclick='saveEdit(this, "text", "<?=$r_lang["code"]?>", "<?=$r_project["text"]?>");'/>
+                                <img class='button_cancel' src='<?=$server?>/img/icon/cancel.png' onclick='cancelEdit(this);'/>
+                                <br/>
+                                <p class='field_result'><?=text($con, $r_project["text"], $r_lang["code"])?></p>
+                                <textarea id='text_<?=$r_lang["code"]?>' class='field_editable'><?=text($con, $r_project["text"], $r_lang["code"])?></textarea>
+                                <script>CKEDITOR.replace('text_<?=$r_lang["code"]?>');</script>
+                            </div>
+                        </div> <!-- .project_add_language -->
+<?php
+                        $active = '';
+                    }
+?>
+                    </div> <!-- #lang_tabs -->
+
+                </div> <!-- .entry -->
+            </div> <!-- .section -->
+        </div> <!-- #content -->
+    </body>
+</html>
+<?php
+            }
+        }
+    }
+?>

+ 162 - 0
www-admin/projects/index.php

@@ -0,0 +1,162 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = $proto . substr($http_host, 0, strpos($http_host, ':')); // public server
+    $lang = "en";
+    if (!check_session($con)){
+        header("Location: /authentication.php");
+        exit(-1);
+    }
+    else{
+?>
+<html>
+    <head>
+        <meta content='text/html; charset=windows-1252' http-equiv='content-type'/>
+        <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1'>
+        <link rel='shortcut icon' href='<?=$pserver?>/img/logo/x2/favicon.ico'/>
+        <title>Projects - I&ntilde;igo Valentin - Administration Panel</title>
+        <style>
+<?php
+            include $doc_root . "css/ui.css";
+            include $doc_root . "css/projects.css";
+?>
+        </style>
+        <!-- CSS for mobile version -->
+        <style media='(max-width : 990px)'>
+<?php
+            include $doc_root . "css/m/ui.css";
+            include $doc_root . "css/m/projects.css";
+?>
+        </style>
+        <!-- Script files -->
+        <script type='text/javascript'>
+<?php
+            include $doc_root . "script/ui.js";
+            include $doc_root . "script/projects.js";
+?>
+        </script>
+    </head>
+    <body>
+<?php
+        include $doc_root . "header.php";
+?>
+        <div id='content'>
+            <div class='section'>
+                <h3 class='section_title'>Project list</h3>
+                <div class='entry'>
+                    <table id='project_list'>
+                        <tr>
+                            <th>Projects</th>
+                            <th>Details</th>
+                            <th>Actions</th>
+                        </tr>
+<?php
+                        $q_project = mysqli_query($con, "SELECT project.id, permalink, project_type.title AS type, project.title AS title, project.logo AS logo, header, text, license.id AS license, concat(fname, concat(' ', lname)) AS user, visible, comments, (SELECT count(id) FROM project_comment WHERE project = project.id) AS comment_count, (SELECT version_name FROM project_version v, project_version_type WHERE type = id AND v.project = project.id ORDER BY version_code DESC LIMIT 1) AS version, (SELECT dtime FROM project_version v WHERE  v.project = project.id ORDER BY version_code DESC LIMIT 1) AS dtime, (SELECT title FROM project_version v, project_version_type WHERE type = id AND v.project = project.id ORDER BY version_code DESC LIMIT 1) AS version_type, (SELECT color FROM project_version v, project_version_type WHERE type = id AND v.project = project.id ORDER BY version_code DESC LIMIT 1) AS version_color, (SELECT image FROM project_image WHERE project = project.id) AS image, (SELECT count(image) FROM project_image WHERE project = project.id) AS image_count FROM project, project_type, license, user WHERE project.type = project_type.id AND project.license = license.id AND project.user = user.id;");
+                        while ($r_project = mysqli_fetch_array($q_project)){
+                            $title = text($con, $r_project["title"],$lang);
+?>
+                            <tr>
+                                <td class='td_project'>
+                                    <h4>
+                                        <a title='View <?=$title?> on a new tab' target='_blank' href='<?=$pserver?>/project/<?=$r_project["permalink"]?>'>
+<?php
+                                            if (strlen($r_project["logo"]) > 0){
+?>
+                                                <img alt='<?=$title?>' title='<?=$title?>' src='<?=$pserver?>/img/project/x2/<?=$r_project["logo"]?>' />
+<?php
+                                            }
+?>
+                                            <?=$title?>
+                                        </a>
+                                    </h4>
+                                    <p><?=cut_text(text($con, $r_project["header"],$lang), 300)?></p>
+<?php
+                                    if ($r_project["image_count"] > 0){
+?>
+                                        <img class='project_image' alt='<?=$title?>' title='<?=$title?>' src='<?=$pserver?>/img/project/x2/<?=$r_project["image"]?>' />
+<?php
+                                        if ($r_project["image_count"] == 2){
+?>
+                                            + other image.
+<?php
+                                        }
+                                        elseif ($r_project["image_count"] > 2){
+                                            $pl = $r_project["image_count"] - 1;
+?>
+                                            + <?=$pl?> other images.
+<?php
+                                        }
+                                    }
+?>
+                                </td>
+                                <td class='td_details'>
+                                    By <?=$r_project["user"]?>.<br/>
+                                    Last version 
+                                    <span style='color:<?=$r_project["version_color"]?>;'>
+                                        <?=$r_project["version"]?> (<?=strtolower(text($con, $r_project["version_type"], $lang))?>)
+                                    </span>
+                                    modified on <?=format_date($r_project["dtime"], $lang, false)?>.<br/>
+                                    Licensed under <?=$r_project["license"]?>.<br/>
+                                    Visible:
+<?php
+                                    if ($r_project["visible"] == 1){
+?>
+                                        Yes
+<?php
+                                    }
+                                    else{
+?>
+                                        No
+<?php
+                                    }
+?>
+                                    <br/>Comments: <?=$r_project["comment_count"]?><br/>
+                                    Comments allowed:
+<?php
+                                    if ($r_project["comments"] == 1){
+?>
+                                        Yes
+<?php
+                                    }
+                                    else{
+?>
+                                        No
+<?php
+                                    }
+?>
+                                </td>
+                                <td class='td_actions'>
+                                    <input type='button' onclick='manageProject(<?=$r_project["id"]?>);' value='Manage / Translate'/>
+                                    <input type='button' onclick='deleteProject(<?=$r_project["id"]?>, "<?=$title?>");' value='Delete'/>
+                                    <input type='button' onclick='TODO' value='Moderate comments'/>
+                                    <?php
+                                    if ($r_project["visible"] == 1){
+?>
+                                        <input type='button' onclick='visibleProject(<?=$r_project["id"]?>, "<?=$title?>", 0);' value='Unpublish'/>
+<?php
+                                    }
+                                    else{
+?>
+                                        <input type='button' onclick='visibleProject(<?=$r_project["id"]?>, "<?=$title?>", 1);' value='Publish'/>
+<?php
+                                    }
+?>
+                                </td>
+                            </tr>
+<?php
+                        }
+?>
+                    </table>
+                </div> <!-- .entry -->
+            </div> <!-- .section -->
+        </div> <!-- #content -->
+    </body>
+</html>
+<?php
+    }
+?>

+ 16 - 0
www-admin/projects/new.php

@@ -0,0 +1,16 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        header("Location: /authentication.php");
+        exit(-1);
+    }
+    else{
+    }
+?>

+ 29 - 0
www-admin/projects/visible.php

@@ -0,0 +1,29 @@
+<?php
+    session_start();
+    $http_host = $_SERVER["HTTP_HOST"];
+    $doc_root = $_SERVER["DOCUMENT_ROOT"] . "/";
+    include $doc_root . "functions.php";
+    $proto = get_protocol();
+    $con = start_db();
+    $server = $proto . $http_host;
+    $pserver = substr($server, 0, strpos($http_host, ':')); // public server
+    if (!check_session($con)){
+        http_response_code(401); // Not logged in: Forbidden.
+    }
+    else{
+        $id = intval(mysqli_real_escape_string($con, $_GET["p"]));
+        $visible = intval(mysqli_real_escape_string($con, $_GET["v"]));
+        if (strlen($id) < 1 || ($visible != 1 && $visible != 0)){
+            http_response_code(400); // No or bad ID, visible not 1 or 0: Bad request.
+        }
+        else{
+            if (mysqli_num_rows(mysqli_query($con, "SELECT id FROM project WHERE id = $id;")) == 0){
+                http_response_code(404); // Unexistent id: Not found.
+            }
+            else{
+                mysqli_query($con, "UPDATE project SET visible = $visible WHERE id = $id;");
+                http_response_code(200); //OK.
+            }
+        }
+    }
+?>

+ 45 - 0
www-admin/script/projects.js

@@ -0,0 +1,45 @@
+function manageProject(id){
+    window.location.href = "/projects/edit.php?p=" + id;
+}
+
+function deleteProject(id, title){
+    dialog("confirm", "Delete project", "Do you really want to delete the project '" + title + "'?<br/><br/>There is no way to undo this action. You can also unpublish the project instead of deleting it.", function (confirmed) {
+        if (confirmed) {
+            var xmlhttp;
+            if (window.XMLHttpRequest){
+                xmlhttp = new XMLHttpRequest();
+            }
+            xmlhttp.onreadystatechange=function(){
+                if (xmlhttp.readyState == 4){
+                    if (xmlhttp.status == 200){
+                        location.reload();
+                    }
+                    else{
+                        dialog("alert", "ERROR", "Error deleting the project '" + title + "'.", null);
+                    }
+                }
+            }
+            xmlhttp.open("GET","/projects/delete.php?p=" + id, true);
+            xmlhttp.send();
+        }
+    });
+}
+
+function visibleProject(id, title, visible){
+    var xmlhttp;
+    if (window.XMLHttpRequest){
+        xmlhttp = new XMLHttpRequest();
+    }
+    xmlhttp.onreadystatechange=function(){
+        if (xmlhttp.readyState == 4){
+            if (xmlhttp.status == 200){
+                location.reload();
+            }
+            else{
+                dialog("alert", "ERROR", "Error changing visibility of the project '" + title + "'.", null);
+            }
+        }
+    }
+    xmlhttp.open("GET","/projects/visible.php?p=" + id + "&v=" + visible, true);
+    xmlhttp.send();
+}

+ 195 - 0
www-admin/script/ui.js

@@ -0,0 +1,195 @@
+/**
+ * Shows one of the headers.
+ * 
+ * @param header Header ID.
+ * @param from Element clicked to open the header. It will be highlighted.
+ */
+function showHeader(header, from){
+    if(document.getElementById('header_' + header).style.display == 'block'){
+        document.getElementById('header_' + header).style.display = 'none';
+        from.style.backgroundColor = '#000000';
+    }
+    else{
+        var headers = document.getElementsByClassName('secondary_header');
+        for (var i = 0; i < headers.length; i ++)
+                headers.item(i).style.display = 'none';
+        var sections = document.getElementsByClassName('header_section');
+        for (var j = 0; j < sections.length; j ++)
+                sections.item(j).style.backgroundColor = '#000000';
+        
+        document.getElementById('header_' + header).style.display = 'block';
+        from.style.backgroundColor = '#333333';
+    }
+}
+
+
+/**
+ * Shows a language tab.
+ * 
+ * @param lang Two letter language code. 'es', 'en' or 'eu'.
+ */
+function showLanguage(lang){
+    switch (lang){
+        case 'es':
+            document.getElementById('content_lang_es').style.display = 'block';
+            document.getElementById('content_lang_eu').style.display = 'none';
+            document.getElementById('content_lang_en').style.display = 'none';
+            document.getElementById('lang_tab_es').classList.add("lang_tabs_active");
+            document.getElementById('lang_tab_eu').classList.remove("lang_tabs_active");
+            document.getElementById('lang_tab_en').classList.remove("lang_tabs_active");
+            break;
+        case 'eu':
+            document.getElementById('content_lang_es').style.display = 'none';
+            document.getElementById('content_lang_eu').style.display = 'block';
+            document.getElementById('content_lang_en').style.display = 'none';
+            document.getElementById('lang_tab_es').classList.remove("lang_tabs_active");
+            document.getElementById('lang_tab_eu').classList.add("lang_tabs_active");
+            document.getElementById('lang_tab_en').classList.remove("lang_tabs_active");
+            break;
+        case 'en':
+            document.getElementById('content_lang_es').style.display = 'none';
+            document.getElementById('content_lang_eu').style.display = 'none';
+            document.getElementById('content_lang_en').style.display = 'block';
+            document.getElementById('lang_tab_es').classList.remove("lang_tabs_active");
+            document.getElementById('lang_tab_eu').classList.remove("lang_tabs_active");
+            document.getElementById('lang_tab_en').classList.add("lang_tabs_active");
+    }
+}
+
+function dialog(type, title, message, callback) {
+    var dialogWindow = document.getElementById('dialog');
+    var dialogText = document.getElementById('dialog_text');
+    var dialogTitle = document.getElementById('dialog_title');
+    var background = document.getElementById('dialog_background');
+    var ynContainer = document.getElementById('dialog_button_yn_container');
+    var aContainer = document.getElementById('dialog_button_a_container');
+    var yButton = document.getElementById('dialog_yes');
+    var nButton = document.getElementById('dialog_no');
+    var aButton = document.getElementById('dialog_accept');
+
+    function show(){
+        dialogTitle.innerText = title;
+        dialogText.innerHTML = message;
+        dialogWindow.style.display = 'block';
+        dialogWindow.style.opacity = '1';
+    };
+    function hide(){
+        dialogWindow.style.display = 'none';
+        dialogWindow.style.opacity = '0';
+    };
+
+    // Set up the dialog type
+    if (type == "confirm"){
+        ynContainer.style.display = "block";
+        aContainer.style.display = "none";
+        yButton.onclick = function() {
+            hide();
+            callback(true);
+        }
+        nButton.onclick = function() { 
+            hide();
+            callback(false);
+        }
+    }
+    else if (type == "alert"){
+        ynContainer.style.display = "none";
+        aContainer.style.display = "block";
+        aButton.onclick = function() {
+            hide();
+            callback(true);
+        };
+    }
+    show();
+}
+
+
+function enableEdit(button){
+    var container = button.parentElement;
+    var fieldResult = container.getElementsByClassName('field_result')[0];
+    var fieldEditable = container.getElementsByClassName('field_editable')[0];
+    var cke = container.getElementsByClassName('cke')[0];
+    var buttonEdit = container.getElementsByClassName('button_edit')[0];
+    var buttonSave = container.getElementsByClassName('button_save')[0];
+    var buttonCancel = container.getElementsByClassName('button_cancel')[0];
+    fieldEditable.value = fieldResult.innerHTML;
+    fieldResult.style.display = 'none';
+    if (typeof(cke) != 'undefined' && cke != null){
+        cke.style.display = 'block';
+    }
+    else{
+        fieldEditable.style.display = 'initial';
+    }
+    buttonEdit.style.display = 'none';
+    buttonSave.style.display = 'initial';
+    buttonCancel.style.display = 'initial';
+}
+
+function saveEdit(button, table, column, id){
+    var container = button.parentElement;
+    var fieldResult = container.getElementsByClassName('field_result')[0];
+    var fieldEditable = container.getElementsByClassName('field_editable')[0];
+    var cke = container.getElementsByClassName('cke')[0];
+    var buttonEdit = container.getElementsByClassName('button_edit')[0];
+    var buttonSave = container.getElementsByClassName('button_save')[0];
+    var buttonCancel = container.getElementsByClassName('button_cancel')[0];
+    var value;
+    if (typeof(cke) != 'undefined' && cke != null){
+        fieldEditable.innerHTML = CKEDITOR.instances['text_en'].getData()
+        fieldResult.innerHTML = fieldEditable.innerHTML;
+        value = escape(fieldEditable.innerHTML);
+    }
+    else{
+        value = escape(fieldEditable.value);
+    }
+    // TODO: Do some validation.
+    
+    var xmlhttp;
+            if (window.XMLHttpRequest){
+                xmlhttp = new XMLHttpRequest();
+            }
+            xmlhttp.onreadystatechange=function(){
+                if (xmlhttp.readyState == 4){
+                    if (xmlhttp.status == 200){
+                        if (typeof(cke) != 'undefined' && cke != null){
+                            cke.style.display = 'none';
+                            fieldEditable.innerHTML = CKEDITOR.instances['text_en'].getData()
+                            fieldResult.innerHTML = fieldEditable.innerHTML;
+                        }
+                        else{
+                            fieldEditable.style.display = 'none';
+                            fieldResult.innerHTML = fieldEditable.value;
+                        }
+                        fieldResult.style.display = 'initial';
+                        buttonEdit.style.display = 'initial';
+                        buttonSave.style.display = 'none';
+                        buttonCancel.style.display = 'none';
+                    }
+                    else{
+                        dialog("alert", "ERROR", "Error saving changes.", null);
+                    }
+                }
+            }
+            xmlhttp.open("GET","/functions/save.php?t=" + table + "&c=" + column + "&v=" + value + "&i=" + id, true);
+            xmlhttp.send();
+}
+
+function cancelEdit(button){
+    var container = button.parentElement;
+    var fieldResult = container.getElementsByClassName('field_result')[0];
+    var fieldEditable = container.getElementsByClassName('field_editable')[0];
+    var cke = container.getElementsByClassName('cke')[0];
+    var buttonEdit = container.getElementsByClassName('button_edit')[0];
+    var buttonSave = container.getElementsByClassName('button_save')[0];
+    var buttonCancel = container.getElementsByClassName('button_cancel')[0];
+    fieldEditable.value = fieldResult.innerHTML;
+    fieldResult.style.display = 'initial';
+        if (typeof(cke) != 'undefined' && cke != null){
+        cke.style.display = 'none';
+    }
+    else{
+        fieldEditable.style.display = 'none';
+    }
+    buttonEdit.style.display = 'initial';
+    buttonSave.style.display = 'none';
+    buttonCancel.style.display = 'none';
+}

+ 0 - 0
www-admin/settings/index.php


+ 0 - 0
www-admin/settings/profile.php


+ 0 - 0
www-admin/stats/index.php