Extension:Quota

Versión
El sistema de cuotas está en su versión 1.0 y tiene fecha de 30 de octubre del 2005

Desarrollo de las Cuotas de Usuario en Mediawiki

 * La necesidad de abordar esta extensión viene dada por el hecho de que cualquier usuario (bien sea humano o un robot), puede sobrecargar el sistema con información inútil y pesada, de modo que merme la capacidad de respuesta de la herramienta. Para ello, y para evitar la subida automatizada de ficheros de imagen (hasta ahora los únicos que permitimos en Mediawiki), Tratamos de desarrollar una modificación sobre el código que permita limitar el tamaño de espacio en disco que sube un usuario, así como una interfaz de control para poder cómodamente establecer diferentes cuotas de usuario, según sus necesidades.

PD.- Está probado sólo bajo la versión 1.4.7 de mediawiki

SpecialUpload.php
En primer lugar, veamos los cambios realizados en el SpecialUpload

debe insertarse el código siguiente en la línea 268 (aproximadamente), justo después del código: return $this->uploadWarning($warning); }		}
 * Esta parte del código hace referencia a la actualización en la base de datos de las cuotas de usuario, a medida que un usuario sube un archivo, se aumenta su cuota consumida en el sistema. Como novedad, se ha implementado un sistema por el que si el usuario es un buen colaborador (su ratio por archivo subido no supera los 300Kb.) se le aumenta su cuota sucesivamente hasta los 80 Megabytes (inicialmente sólo dispone de 10). Gracias a esto, se premia los buenos colaboradores. En cambio, si un usuario lo que hace es subir imágenes de mucho peso, se le limita la subida a 10 Mb. y cuando llegue el momento en que haya colmado su cuota, tendrá que ponerse en contacto con el administrador de sistema para poder subir más archivos. Los buenos colaboradores también necesitarán ponerse en contacto con el administrador para aumentar su cuota por encima de los 80 Mb. pudiendo llegar hasta un máximo de 1Gb.
 * NOTA:  Debe recordarse que las tablas en la base de datos pueden llevar un prefijo, cosa que no está considerada en esta modificación. Para ello, sólo habrá que cambiar en el código el nombre de la tabla, por ejemplo, user, por el nombre actual con su prefijo, por ejemplo, prefijo_user, de manera que las modificaciones se hagan de forma correcta.

//Cuotas: La actualización de las cuotas de usuario debe hacerse aquí *********************** $dbr =& wfGetDB( DB_SLAVE ); $iduser=$wgUser->getID; $sql2 = "SELECT user_cuote FROM user WHERE user_id = ".$iduser; $res1 = $dbr->query( $sql2, "Uploadform::processUpload" ); if (!( 0 == $dbr->numRows( $res1 )) ) { $cuote=mysql_result($res1,0,0); }			$sql3 = "SELECT user_cuote_used FROM user WHERE user_id = ".$iduser; $res2 = $dbr->query( $sql3, "Uploadform::processUpload" ); if (!( 0 == $dbr->numRows( $res2 )) ) { $cuote_used=mysql_result($res2,0,0); }			if ($this->mUploadSize+$cuote_used>$cuote) //el usuario excede su cuota {								//primero obtenemos el nombre del usuario, ya que en la tabla image //sólo aparece el nombre del usuario, y no su identificador $sqln1 = "SELECT user_name FROM user WHERE user_id = ".$iduser; $resn1 = $dbr->query( $sqln1, "Uploadform::processUpload" ); if (!( 0 == $dbr->numRows( $resn1 )) ) { $name_user=mysql_result($resn1,0,0); }					//buscamos en la tabla de imágenes el número de imágenes que ha subido el usuario. $sqln = "SELECT distinct count(*) from `image` WHERE img_user_text=\"".$name_user."\""; $resn = $dbr->query( $sqln, "Uploadform::processUpload" ); if ( 0 != $dbr->numRows( $resn ) ) { $number_uploads=mysql_result($resn,0,0); //número de imágenes subidas } //con esto tenemos el número de archivos que ha subido el usuario if ($number_uploads==0){ $wgOut->addHTML( " Error de División por cero " ); return; }						if (($cuote_used/$number_uploads<300000)&&($cuote<60000000)){ //es un buen usuario, no sobrecarga el sistema, lo llena de contenidos //Ampliamos su cuota al doble $actualizada=$cuote*2; $sql5 = "UPDATE user SET user_cuote = '".$actualizada."' WHERE user_id = ".$iduser; $res3 = $dbr->query( $sql5, "Uploadform::processUpload" ); $this->uploadError( wfMsg( 'gooduserwarning' ) ); $wgOut->addHTML( " Hemos ampliado su cuota a $actualizada bytes \n" ); //actualizamos la cuota usada $actualizada=$this->mUploadSize+$cuote_used; $sql4 = "UPDATE user SET user_cuote_used = '".$actualizada."' WHERE user_id = ".$iduser; $res2 = $dbr->query( $sql4, "Uploadform::processUpload" ); }else{ $rest=$cuote-$cuote_used; $this->uploadError( wfMsg( 'quoteoverload' ) ); $wgOut->addHTML( " SÃ³lo puede subir $rest bytes \n" ); return; }			}else{ //se actualiza la cuota del usuario $actualizada=$this->mUploadSize+$cuote_used; $sql4 = "UPDATE user SET user_cuote_used = '".$actualizada."' WHERE user_id = ".$iduser; $res2 = $dbr->query( $sql4, "Uploadform::processUpload" ); }			//Cuotas**************************************************************************************

UserList.php

 * Hemos de crear el nuevo fichero UserList.php, con el código siguiente:

query( $sql, "UserList::UserList" ); if ( 0 == $dbr->numRows( $res ) ) { echo "ERROR, NO HAY RESULTADOS PARA ESTA CONSULTA DE USUARIOS"; die; }	while ( $row = $dbr->fetchObject ( $res ) ) { $this->mQuotesList[$row->user_id] = $row; }	$dbr->freeResult ($res); } }

?>
 * NOTA:  Debe recordarse que las tablas en la base de datos pueden llevar un prefijo, cosa que no está considerada en esta modificación. Para ello, sólo habrá que cambiar en el código el nombre de la tabla, por ejemplo, user, por el nombre actual con su prefijo, por ejemplo, prefijo_user, de manera que las modificaciones se hagan de forma correcta.
 * Con este fichero, hacemos la consulta a la base de datos para obtener la lista de los usuarios del sistema y sus cuotas y cuotas consumidas. La idea es tener toda la información que necesitaremos del sistema para gestionar las cuotas de usuario. Debe estar situado en la carpeta de includes de mediawiki ( /includes );

/extension/Quotes.php
<?php
 * NOTA:  Debe recordarse que las tablas en la base de datos pueden llevar un prefijo, cosa que no está considerada en esta modificación. Para ello, sólo habrá que cambiar en el código el nombre de la tabla, por ejemplo, user, por el nombre actual con su prefijo, por ejemplo, prefijo_user, de manera que las modificaciones se hagan de forma correcta.

if (!defined('MEDIAWIKI')) die; $wgExtensionFunctions[] = "wfQuoteExtension";

function display_size($size) {

static $gb, $mb, $kb, $b;

if (empty($gb)) { $gb = "Gb."; $mb = "Mb."; $kb = "Kb."; $b = "bytes"; }

if ($size >= 1073741824) { $size = round($size / 1073741824 * 10) / 10. $gb; } else if ($size >= 1048576) { $size = round($size / 1048576 * 10) / 10. $mb; } else if ($size >= 1024) { $size = round($size / 1024 * 10) / 10. $kb; } else { $size = $size .' '. $b; }   return $size; }

function wfQuoteExtension { global $IP, $wgMessageCache; global $wgUser; require_once( "$IP/includes/SpecialPage.php" );

$wgMessageCache->addMessages(                            array( // Here you should define the article name that contains the Special Page's Title as shown in Special:Specialpages // Where 'specialpagename' will be MediaWiki: eg. Special:Allpages might be 'allpages' // The part after '=>' is the default value of the title so again, using Special:Allpages as an example you wuold have... // 'allpages' => 'All Pages'; // the part BEFORE the => must be all Lowercase. 'cuotasusuario' => 'Cuotas de Usuario')                               );

class SpecialQuote extends SpecialPage { var $mUser, $mQuote, $mPosted, $mNewQuote, $mQuoteUsed;

function SpecialQuote { global $wgUser, $wgRequest; $this->mNewQuote=0; $this->mQuoteUsed=0; $this->QuoteForm( $wgRequest ); if (!(($wgUser->isSysop)||($wgUser->isBureaucrat))) {										wfMsg("Usted no es administrador ni burócrata, acceso denegado"); return; }                                    SpecialPage::SpecialPage( 'CuotasUsuario' ); }			 function QuoteForm( &$request ) { global $wgLang,$wgUser; $this->mUser = $request->getVal( 'wpUserId' ); $this->mQuote = $request->getVal( 'wpStore' ); $this->mPosted = $request->wasPosted; }           			 function QuoteForm2( &$request ) { global $wgLang,$wgUser; $this->mNewQuote = $request->getVal( 'wpStore' ); $this->mPosted = $request->wasPosted; $this->mUser = $request->getVal( 'UserId' ); $this->mQuote = $request->getVal( 'Store' ); $this->mQuoteUsed=$request->getVal( 'StoreUsed' ); }

function execute( $par = null ) { global $wgOut, $wgRequest; global $wgUser, $wgLang, $wgUploadDirectory; $cols = intval($wgUser->getOption( 'cols' )); $ew = $wgUser->getOption( 'editwidth' ); if ( $ew ) $ew = " style=\"width:100%\""; else $ew = ''; $sub = "Cuotas de usuario"; $wgOut->addHTML( " {$sub} \n" ); $sk = $wgUser->getSkin; $wgOut->addHTML( "										 										  " ); global $relleno; $relleno=0; if ($this->mPosted){ if ($this->mUser=="Elija Usuario"){ $wgOut->addHTML( " Debe elegir un usuario "); $this->mUser=0; $this->mQuote=0; return; }else{ $dbr =& wfGetDB( DB_SLAVE ); $sql1 = "SELECT user_cuote FROM user WHERE user_name = \"".$this->mUser."\""; $res1 = $dbr->query( $sql1, "Quotes::execute" ); if ( 0 == $dbr->numRows( $res1 ) ) { //echo "No hay cuota en la BBDD"; global $relleno; $relleno=1; }else{ $Cuota=mysql_result($res1,0,0); }													$sql2 = "SELECT user_cuote_used FROM user WHERE user_name = \"".$this->mUser."\""; $res2 = $dbr->query( $sql2, "Quotes::execute" ); if ( 0 == $dbr->numRows( $res2 ) ) { //echo "No hay cuota usada en la BBDD"; global $relleno; $relleno=1; }else{ $Cuota_usada=mysql_result($res2,0,0); }													$Cuota_c=display_size($Cuota); $Cuota_usada_c=display_size($Cuota_usada); if ($relleno==0){ $wgOut->addHTML(" " 				   											); $wgOut->addHTML( " ".wfMsg('selectQuote')."															Elija Cuota 															10 Mb. 															20 Mb. 															50 Mb. 															100 Mb. 															500 Mb. 															1 Gb. 															0 Sin cuota 																														mUser\">																																													 "); }													if ($this->mNewQuote==0) {															$this->QuoteForm2($wgRequest); $Nueva_Cuota=0; switch ($this->mNewQuote) { case "0" : $wgOut->addHTML( " Debe elegir una cuota tras seleccionar el usuario " ); return; break; case "1" : $Nueva_Cuota=10*1024*1024; break; case "2" : $Nueva_Cuota=20*1024*1024; break; case "3" : $Nueva_Cuota=50*1024*1024; break; case "4" : $Nueva_Cuota=100*1024*1024; break; case "5" : $Nueva_Cuota=500*1024*1024; break; case "6" : $Nueva_Cuota=1024*1024*1024; break; case "7" : $Nueva_Cuota=0; break; default : $Nueva_Cuota=-1; break; }															$Cuota_Old_c=display_size($this->mQuote); $Cuota_usada_c=display_size($this->mQuoteUsed); $Nueva_Cuota_c=display_size($Nueva_Cuota); if ($Nueva_Cuota!=-1){ $mensaje="La cuota ha sido actualizada a:"; if ($this->mQuoteUsed>$Nueva_Cuota) {																	$mensaje="La cuota no ha podido actualizarse"; $Nueva_Cuota_c="Error"; }																$wgOut->addHTML(" " 					   											); if (!($this->mQuoteUsed>$Nueva_Cuota)){ $sql4 = "UPDATE user SET user_cuote = '".$Nueva_Cuota."' WHERE user_name = '".$this->mUser."'"; $res2 = $dbr->query( $sql4, "ImagePage::doDelete" ); $exito="La cuota del usuario $this->mUser ha sido actualizada"; $wgOut->addHTML( " {$exito} " ); }else{ $fracaso="La cuota usada por el usuario $this->mUser no puede ser mayor a la nueva cuota"; $wgOut->addHTML( " {$fracaso} " ); }															}																	}													}										 }										}		       		                                          } SpecialPage::addPage( new SpecialQuote ); } ?>

ImagePage.php
//***********************************************************************************			#Cuotas: Para realizar la actualización de la cuota del usuario hay que hacerla aquí. $dbr =& wfGetDB( DB_SLAVE ); $image = $this->mTitle->getDBkey;	//obtenemos el identificador de la imagen //obtenemos el tamaño de la imagen $sql22 = "SELECT img_size FROM image WHERE img_name = '".$image."'"; $res12 = $dbr->query( $sql22, "ImagePage::doDelete" ); if (!( 0 == $dbr->numRows( $res12 )) ) { $size=mysql_result($res12,0,0); }else{ echo "Error en la imagen $image línea 391 de ImagePage.php"; return;} //Seleccionamos el nombre del usuario de la tabla de la imagen $sql21 = "SELECT img_user_text FROM image WHERE img_name = '".$image."'"; $res11 = $dbr->query( $sql21, "ImagePage::doDelete" ); if (!( 0 == $dbr->numRows( $res11 )) ) { $user_name=mysql_result($res11,0,0); }else{ echo "no existe el usuario: $iduser"; return;} //Seleccionamos la cuota del usuario de la tabla de usuarios $sql2 = "SELECT user_cuote FROM user WHERE user_name = '".$user_name."'"; $res1 = $dbr->query( $sql2, "ImagePage::doDelete" ); if (!( 0 == $dbr->numRows( $res1 )) ) { $cuote=mysql_result($res1,0,0); }			//Seleccionamos la cuota usada por el usuario de la tabla de usuarios $sql3 = "SELECT user_cuote_used FROM user WHERE user_name = '".$user_name."'"; $res2 = $dbr->query( $sql3, "ImagePage::doDelete" ); if (!( 0 == $dbr->numRows( $res2 )) ) { $cuote_used=mysql_result($res2,0,0); }			if ($cuote_used-$size>=0) //calculamos el espacio, no puede ser negativo {						$wgOut->setPagetitle( wfMsg( 'deletiondone' ) ); //título de la página $actualizada=$cuote_used-$size; //calculamos la nueva cuota usada $sql4 = "UPDATE user SET user_cuote_used = '".$actualizada."' WHERE user_name = '".$user_name."'"; $res2 = $dbr->query( $sql4, "ImagePage::doDelete" ); $wgOut->addHTML( " Cuota del usuario $user_name actualizada a $actualizada bytes \n" ); }else{ $wgOut->setPagetitle( wfMsg( 'deletionerror' ) ); //título de la página $wgOut->addHTML( " ".wfMsg( 'deletionInconsistence' )." \n" ); //return; $actualizada=0; //si el espacio sale negativo, se pone la cuota usada a 0 $sql5 = "UPDATE user SET user_cuote_used = '".$actualizada."' WHERE user_name = '".$user_name."'"; $res3 = $dbr->query( $sql5, "ImagePage::doDelete" ); $wgOut->addHTML( " Cuota del usuario $user_name actualizada a $actualizada bytes \n" ); }			//Cuotas**************************************************************************************
 * Los cambios en ImagePage están situados en la función doDelete, hacia el número de línea 378. Estos cambios sirven para el borrado de la imagen principalmente y la actualización de la cuota de usuario usada.
 * NOTA:  Debe recordarse que las tablas en la base de datos pueden llevar un prefijo, cosa que no está considerada en esta modificación. Para ello, sólo habrá que cambiar en el código el nombre de la tabla, por ejemplo, user, por el nombre actual con su prefijo, por ejemplo, prefijo_user, de manera que las modificaciones se hagan de forma correcta.


 * Hemos considerado para ello, que la cuota en un momento dado puede ser negativa (me refiero a la cuota usada), ya que la base de datos cuando se produce la instalación de esta extensión, no tiene por qué estar vacía, y puede que un usurio haya subido imágenes previamente a la instalación de la extensión de las cuotas. En ese caso, modificamos y ponemos a cero la cuota del usuario.


 * El funcionamiento del algoritmo es el siguiente a grandes rasgos:
 * 1) Obtención de la clave de la imagen a borrar.
 * 2) Ontención del nombre del usuario de la tabla de la imagen que subió la imagen. Nótese que este no tiene por qué ser el usuario que está conectado en este momento $wgUser, ya que sólo el administrador del sistema puede borrar fotos. Por lo general no serán suyas las que borre.
 * 3) Obtención de la cuota que tiene el usuario del punto anterior en el sistema para subir los archivos y qué parte de esa cuota ya está consumida.
 * 4) restamos el tamaño de la imagen a la cuota consumida y actualizamos la cuota consumida. Si la resta da un número negativo, quedará establecida en 0.

languages/LanguageEs.php

 * Cambios en el fichero de lenguaje. Añadir los siguientes mensajes al castellano;

'quoteoverload'=> "No puede subir el fichero, superada su capacidad de almacenamiento. Póngase en contacto con el administrador del sistema. ", 'gooduserwarning'=> "Ha llegado al máximo de su capacidad de almacenamiento como usuario. Como ha respetado nuestra política de no subir ficheros pesados (más de 300Kb. por fichero), hemos aumentado su cuota al doble automáticamente. Gracias por colaborar con la Commonpedia. ", 'deletiondone'	=> "Borrado efectuado", 'deletionerror'	=> "El borrado ha fallado", 'selectUser'	=> "Seleccione un usuario: ", 'selectQuote'	=> "Seleccione la cuota de usuario: ", 'deletionInconsistence'	=> "Ha sucedido una pequeña inconsistencia, la cuota quedaba negativa. Puede ser que las modificaciones sobre el código se hayan producido posteriormente a la instalación. ",

Cambios en la base de datos
ALTER TABLE `user` ADD `user_cuote` INT( 11 ) UNSIGNED DEFAULT '10485760' NOT NULL; ALTER TABLE `user` ADD `user_cuote_used` INT( 11 ) UNSIGNED DEFAULT '0' NOT NULL ;
 * Los cambios en la base de datos están encaminados a añadir para cada usuario, dos campos nuevos, el primero (user_cuote) establece la cuota de usuario que va a ser asignada al usuario, esto es, el tamaño máximo de subida que podrá usar el usuario. Por defecto, este tamaño está establecido a 10Mb. El otro campo (user_cuote_used) sirve para ir almacenando las sumas parciales de los archivos que va subiendo. Como valor inicial, tendrá 0 ya que al principio no se sube nada.
 * NOTA:  Debe recordarse que las tablas en la base de datos pueden llevar un prefijo, cosa que no está considerada en esta modificación. Para ello, sólo habrá que cambiar, por ejemplo, user por prefijo_user, de manera que las modificaciones se hagan de forma correcta.

Instalación
Para instalar la extensión de las Cuotas de usuario, hay que seguir los siguientes pasos:


 * 1) Copiar el fichero Quotes al directorio de mediawiki /extensions (o crearlo con el código aquí indicado).
 * 2) Sobreescribir cada uno de los ficheros aquí cambiados, o bien añadir el código indicado en cada uno de ellos.
 * 3) Copiar el fichero UserList.php en la carpeta de mediawiki /includes, o bien crearlo con el código aquí indicado.
 * 4) Añadir al LocalSettings.php la siguiente línea al final del fichero, justo antes del cierre en php ?>

require_once('extensions/Quotes.php');


 * Con esto debería funcionar la instalación

Funcionamiento

 * Estos son los pasos clave para manejar la nueva modificación en la que se consideran y pueden usarse cuotas de subida de ficheros para los usuarios:

1º - Logarte en la commonpedia de prueba como Sysop (cuentas de administrador) 2º - Ir a páginas especiales (hacia el final, existe una que hemos llamado cuotas de usuario) 3º - Seleccionar en el desplegable uno de los usuarios del sistema (que están por orden alfabético) 4º - Pulsar el botón de mostrar el usuario (se muestra una tabla con los datos relevantes del usuario y un nuevo desplegable con las cuotas) 5º - Seleccionar la cuota nueva que se quiere establecer para el usuario mostrado en la tabla (la nueva cuota tiene que ser mayor que la cuota consumida actualmente por el usuario) 6º - Pulsar el botón de Cambiar cuota.


 * Una vez hechos estos pasos, pueden verse los cambios con los puntos 2º, 3º y 4º.

Licencia
Este artículo se licencia bajo Creative Commons by-nc-sa. Puede seguir el siguiente enlace para más información: http://creativecommons.org/licenses/by-nc-sa/2.5/es/

El Código fuente tiene licencia Gnu GPL