class cwForm {
var $elements;
var $form_id;
function cwForm($name = 'cwForm'){
$this->elements = array();
$this->form_id = 1;
}
function set_id($id){
$this->form_id = $id;
}
function get_id(){
return $this->form_id;
}
function get_html_id(){
return 'form_' . $this->form_id;
}
function add($element){
$this->elements[] = &$element;
}
function &get_ctl( $pname ){
$count = count($this->elements);
for( $i = 0; $i < $count; $i++){
$ctl =& $this->elements[$i];
if( $ctl->get_pname() == $pname )
return $ctl;
}
echo "Can't find control named '$pname'!
";
return;
}
function submitted(){
global $HTTP_POST_VARS;
if( isset($HTTP_POST_VARS[ $this->get_html_id() ]) )
return 1;
else
return 0;
}
function validate(){
global $HTTP_POST_VARS;
$bad = 0;
$count = count( $this->elements );
for($i = 0; $i < $count; $i++){
$el = & $this->elements[$i];
$el->set_value( $HTTP_POST_VARS[$el->get_name()] );
if( ! $el->validate() )
$bad++;
}
if( $bad )
return 0;
else
return 1;
}
function show(&$tpl, $buttons = array('update'), $file = 'admin_mwobject.tpl'){
$tpl->set_file('form', $file, 1);
reset($this->elements);
foreach($this->elements as $el){
if( $el->get_error() ){
$tpl->set_var('ERROR', $el->get_error());
$error = $tpl->process('', 'error_block');
}
else
$error = '';
$els_loop[] = array(
'TITLE' => $el->get_title(),
'NAME' => $el->get_name(),
'EDIT_VALUE' => $el->get_edit_value(),
'ERROR' => $error,
);
}
$tpl->set_loop('elements', $els_loop);
//setting buttons
$btn_loop = array();
foreach( $buttons as $but){
$btn_loop[] = array(
'BUTTON' => $tpl->process('', 'button_'.$but),
);
}
$tpl->set_loop('buttons', $btn_loop);
$tpl->set_var('FORM_ID', $this->get_html_id());
return $tpl->process('out', 'form', 1);
}
}
class cwDate extends cwFormElement {
function cwDate($name, $title=''){
$this->cwFormElement($name, $title);
}
function get_edit_value(){
if( ! $this->get_value() ) //new item, doesn't have date
$this->set_value( date("M j, Y", time()) );
$readonly = 'CLASS="readonly" READONLY';
$date_str = date( "M j, Y", $this->get_value() );
$string = '';
$string .= '';
return $string;
}
}
class cwSelect extends cwFormElement {
var $fill;
var $sel;
function cwSelect($name, $title='', $fill = array(), $sel = 0 ){
$this->cwFormElement($name, $title);
$this->fill = $fill;
$this->sel = $sel;
}
function get_edit_value(){
$string = '';
return $string;
}
}
class cwHidden extends cwFormElement {
function cwHidden($name, $title=''){
$this->cwFormElement($name, $title);
}
function get_edit_value(){
return '';
}
}
class cwTextarea extends cwFormElement {
function cwTextarea($name, $title=''){
$this->cwFormElement($name, $title);
// setting view defaults
$this->set_view('cols', 48);
$this->set_view('rows', 8);
}
function get_edit_value(){
return '';
}
}
class cwPassword extends cwFormElement {
var $name2;
var $value2;
function cwPassword($name, $title=''){
$this->cwFormElement($name, $title);
// setting view defaults
$this->set_view('size', 24);
$this->set_name2( $this->get_name() . '_confirm' );
$this->set_value2('');
}
function get_edit_value(){
$readonly = ( $this->is_readonly() ) ? 'CLASS="readonly" READONLY' : '';
// $edit_code = ' ';
// $edit_code .= 'Confirm: ';
// don't out the value
$edit_code = ' ';
$edit_code .= 'Confirm: ';
return $edit_code;
}
function validate(){
if ( cwFormElement::validate() ){
$bad = 0;
$message = 'Passwords differ!';
if( $this->get_value() != $this->get_value2() )
$bad++;
if ($bad) {
$this->set_error( $message );
return 0;
}
else
return 1;
}
else
return 0;
}
function set_name2($name){
$this->name2 = $name;
}
function get_name2(){
return $this->name2;
}
function grab_value(){
global $HTTP_POST_VARS;
$this->set_value( trim($HTTP_POST_VARS[$this->get_name()]) );
$this->set_value2( trim($HTTP_POST_VARS[$this->get_name2()]) );
}
function set_value2($value2){
$this->value2 = $value2;
}
function get_value2(){
return $this->value2;
}
}
class cwTextbox extends cwFormElement {
function cwTextBox($name, $title=''){
$this->cwFormElement($name, $title);
// setting view defaults
$this->set_view('size', 24);
}
function get_edit_value(){
global $sid, $adaptor;
$readonly = ( $this->is_readonly() ) ? 'CLASS="readonly" READONLY' : '';
$edit_code = '';
if( $this->get_pname() == 'hits' )
$edit_code .= "\n";
if( $this->get_pname() == 'user_email' ) {
$email = $this->get_value();
if( $email ) {
$users = $adaptor->retrieve_where('mwlUser', "email=$email");
if( count($users) > 0 ){
$user = $users[0];
$uid = $user->get_property('_id');
$edit_code .= " email\n";
}
}
}
// if( $this->get_pname() == 'url' )
// $edit_code .= " get_value() . "\">open\n";
return $edit_code;
}
}
class cwFormElement {
var $name;
var $pname;
var $title;
var $value;
var $readonly;
var $error;
var $checks;
var $view;
function cwFormElement($name, $title = ''){
$this->set_name($name);
if($title)
$this->set_title($title);
else
$this->set_title('');
$this->readonly = false;
$this->checks = array();
$this->view = array();
$this->error = '';
}
function set_readonly($set = true){
$this->readonly = $set;
}
function is_readonly(){
return $this->readonly;
}
function set_view($param, $value){
$this->view[$param] = $value;
}
function get_view($param){
return $this->view[$param];
}
function validate(){
$bad = 0;
foreach( $this->checks as $check ){
$message = $check[0];
$regex = $check[1];
if ( $regex ){ //checking for regex
if( ! preg_match($regex, $this->get_value()) )
$bad++;
}
else { //just check for value
if( ! $this->get_value() )
$bad++;
}
if ($bad) {
$this->set_error( $message );
break;
}
}
if( $bad )
return 0;
else{
return 1;
}
}
function add_check($message, $regex = ''){
$this->checks[] = array($message, $regex);
}
function set_title($title){
$this->title = $title;
}
function get_title(){
return $this->title;
}
function set_name($name){
$this->name = $name;
}
function get_name(){
return $this->name;
}
function set_pname($pname){
$this->pname = $pname;
}
function get_pname(){
return $this->pname;
}
function grab_value(){
global $HTTP_POST_VARS;
$this->set_value( trim($HTTP_POST_VARS[$this->get_name()]) );
}
function set_value($val){
$this->value = $val;
}
function get_value(){
return $this->value;
}
function set_error($err){
$this->error = $err;
}
function get_error(){
if( isset($this->error) )
return $this->error;
}
}
?>
class mwAdaptor {
var $dbf;
function mwAdaptor(&$dbf){
$this->dbf =& $dbf;
return 1;
}
function retrieve_where($class, $string=''){
// first argument is $class
// then passed the string with conditions
// like parent_id=1 AND date>100
global $schema;
$arg_list = array();
if( $string ){
if( preg_match("/OR/", $string) )
$logic = 'OR';
else
$logic = 'AND';
$arg_list[] = $logic;
$conditions = preg_split("/\s+".$logic."\s+/", $string);
foreach($conditions as $c){
preg_match("/(.+)([=><%!])(.+)/", $c, $m);
$arg_list[] = $m[1];
$arg_list[] = $m[2].$m[3];
}
}
$file = &$this->dbf[ $schema[$class]['file'] ];
//first coming 'AND' or 'OR'
//$arg_list is (pname, value) x n times
$array = $file->get_where($arg_list); //returned array of nodes
$count = count($array);
for($i = 0; $i < $count; $i++){
$obj = new $class;
$obj->set_by_array( $array[$i] );
$obj->load();
$array[$i] = $obj;
}
return $array;
}
function count_where($class, $string=''){
// first argument is $class
// then passed the string with conditions
// like parent_id=1 AND date>100
global $schema;
$arg_list = array();
if( $string ){
if( preg_match("/OR/", $string) )
$logic = 'OR';
else
$logic = 'AND';
$arg_list[] = $logic;
$conditions = preg_split("/\s+".$logic."\s+/", $string);
foreach($conditions as $c){
preg_match("/(.+)([=><%!])(.+)/", $c, $m);
$arg_list[] = $m[1];
$arg_list[] = $m[2].$m[3];
}
}
$file = &$this->dbf[ $schema[$class]['file'] ];
//first coming 'AND' or 'OR'
//$arg_list is (pname, value) x n times
$count = $file->count_where($arg_list); //returned array of nodes
return $count;
}
function load(&$obj){
global $schema;
$id = $obj->get_property('_id');
$class = $obj->get_property('_class');
$file = &$this->dbf[ $schema[$class]['file'] ];
$prop_names = $obj->get_prop_names();
$node = $file->get($id);
if( ! $node )
return 0;
while(list($key, $pname) = each($prop_names)){
$ps = $schema[$class]['properties']["$pname"]; //property data hash
if($pname == '_id') //don't reload id
continue;
$obj->set_property($pname, $node[$pname]);
}
return 1;
}
function delete(&$obj){
global $schema;
$id = $obj->get_property('_id');
$object_file = &$this->dbf[ $schema[$obj->get_property('_class')]['file'] ];
$object_file->delete($id);
unset($obj);
}
function get_obj($id, $class_name = ''){
global $ROOT_CLASS, $schema;
if( ! $class_name )
$class_name = $ROOT_CLASS;
$obj = new $class_name($id);
return $obj;
}
function store(&$obj){
global $schema;
$count = 0;
$prop_names = $obj->get_prop_names();
$class = $obj->get_property('_class');
$object_file = &$this->dbf[ $schema[$class]['file'] ];
$id = $obj->get_property('_id');
$node = array();
while(list($key, $pname) = each($prop_names)){
$node[$pname] = unhtmlentities( $obj->get_property($pname) );
}
// new object, get id for it
if($id <= 0){
$id = $object_file->add( $node );
$obj->set_property('_id', $id);
}
else{
$object_file->save($id, $node);
}
return $id;
}
}
?>
class mwBackupFile {
var $dir;
var $prefix;
var $tables;
var $files;
var $status;
function mwBackupFile($dir, $prefix = 'backup', $tables = array()){
global $post, $HTTP_POST_VARS, $dbh, $PERM;
$this->dir = $dir;
$this->prefix = $prefix;
$this->tables = $tables;
$this->files = array();
$this->status = '';
if( isset($post['action']) ){
switch( $post['action'] ){
case 'backupdelete':
$fname = $HTTP_POST_VARS['mwBackups'];
$this->delete($fname);
break;
case 'backupcreate':
$this->create();
break;
case 'backupupload':
if( $PERM['BACKUP_UPLOAD'] ){
$this->upload();
}
else{
out( 'Sorry, this action is disabled
' );
}
break;
case 'backuprestore':
if( $PERM['BACKUP_RESTORE'] ){
$fname = $HTTP_POST_VARS['mwBackups'];
$this->restore($fname);
}
else{
out( 'Sorry, this action is disabled
' );
}
break;
default:
if(! $this->status)
$this->status = 'An action ' . $post['action'] .' occured but I cannot find a handler for it';
}
}
if($dir = @opendir($dir) ){
while ( ($file = readdir($dir)) != false ){
if(substr($file, 0, strlen($prefix)) == $prefix)
$this->files[] = $file;
}
}
else {
if(! $this->status)
$this->status = 'Cannot open backup directory';
return;
}
}
function upload(){
global $HTTP_POST_FILES;
if( ! $HTTP_POST_FILES['backupfile']['name'] )
return;
if( is_uploaded_file($HTTP_POST_FILES['backupfile']['tmp_name']) ){
if( $this->check_fname($HTTP_POST_FILES['backupfile']['name']) ){
copy($HTTP_POST_FILES['backupfile']['tmp_name'], $this->dir . '/' . $HTTP_POST_FILES['backupfile']['name']);
}
else {
if(! $this->status)
$this->status = 'Bad backup filename. It should look like dsbackup_YYYY_MM_DD_HH_MM.sql
You submitted: ' . $HTTP_POST_FILES['backupfile']['name'] . '';
}
}
else {
if(! $this->status)
$this->status = "Error when uploading file. Filename: " . $HTTP_POST_FILES['backupfile']['name'];
}
// move_uploaded_file($_FILES['backupfile']['tmp_name'], $this->dir . '/' . $HTTP_POST_FILES['backupfile']['name']);
if(! $this->status)
$this->status = 'Backup file has been uploaded';
}
function check_fname($fname){
if( preg_match("/^ldbackup_\d{4}_\d{2}_\d{2}_\d{2}_\d{2}\.sql$/", $fname) )
return 1;
else
return 0;
}
function delete($fname){
if( @unlink($this->dir . '/' . $fname) )
$this->status = 'File deleted';
else
$this->status = 'Cannot delete file';
}
function download($fname){
$fname = $this->dir . '/' . $fname;
$saveasname = basename($fname);
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($fname));
header('Content-Disposition: attachment; filename="'.$saveasname.'"');
readfile($fname);
}
function show(&$tpl, $tplfile = 'admin_backup.tpl'){
$filesloop = array();
$tpl->set_file('main', $tplfile);
$num_files = count($this->files);
for($i = 0; $i < $num_files; $i++){
$fname = $this->files[$i];
$fs = explode("_", substr($fname, 0, strlen($fname) - 4 ) );
$ftitle = 'Backup of '.$fs[1].'/'.$fs[2].'/'.$fs[3].' '.$fs[4].':'.$fs[5];
$filesloop[$i] = array(
"FNAME" => $fname,
"FTITLE" => $ftitle,
);
}
$tpl->set_loop('files', $filesloop);
if(! $this->status)
$this->status = 'OK';
$tpl->set_var('STATUS', $this->status);
return $tpl->process('out', 'main', 1);
}
//REALIZATION SPECIFIC STUFF
function create(){
global $dbf;
$fname = $this->dir . '/' . $this->prefix . date('Y_m_d_H_i') . '.sql';
if(! $file = @fopen($fname, 'w') ){
$this->status = "Cannot open file $fname for writing";
return;
}
// should create something like this
// INSERT INTO mwobject(_id, _class) VALUES ("3", "mwfQuestion")
foreach($this->tables as $table){
$db_file = $dbf[$table];
for( $id = 1; $id <= $db_file->max(); $id++ ){
$array = $db_file->get($id);
if(! isset($array['_id']) )
continue;
$sql_stat = 'INSERT INTO ' . $table . ' (';
$sql_stat .= implode(', ', array_keys($array) );
$sql_stat .= ') VALUES ("';
$sql_stat .= implode('", "', array_values($array) );
$sql_stat .= '")';
fwrite($file, "$sql_stat\n");
}
}
fclose($file);
$this->status = "New backup file has been successfully created";
}
function restore($fname){
global $dbf;
if(! $file = @fopen($this->dir . '/' . $fname, 'r') ){
$this->status = "Cannot open file $fname for reading";
return;
}
//deleting old data
foreach($this->tables as $table){
$db_file = $dbf[$table];
$db_file->drop();
}
while ( !feof ($file) ) {
$line = fgets($file, 16384);
$line = trim($line);
// parse the line like this
// INSERT INTO mwobject(_id, _class) VALUES ("3", "mwfQuestion")
// INSERT INTO (.+)\((.+)\) VALUES \((.+)\)
if(strlen($line) <= 0 )
continue;
preg_match("/INSERT\s+INTO\s+(.+)\s+\((.+)\)\s+VALUES\s+\((.+)\)/", $line, $m);
$db_filename = trim( $m[1] );
$props = explode(',', $m[2]);
$values = explode(',', $m[3]);
$qty = count($props);
for($i = 0; $i < $qty; $i++){
$p = preg_replace( "/^\"?(.*)\"?$/U", "\\1", trim($props[$i]) ); //U stands for ungreedy, different from perl
$v = preg_replace( "/^\"(.*)\"$/", "\\1", trim($values[$i]) );
$node[$p] = $v;
}
if( isset( $dbf[$db_filename] ) ){
$db_file = $dbf[$db_filename];
$db_file->save($node['_id'], $node);
}
}
@fclose($file);
$this->status = "Data have been restored from a backup file";
}
}
?>
class mwConf {
var $filename;
var $props;
var $confvar;
function mwConf($filename, $props, $prefix = '', $confvar = 'CONF'){
global $PERM, $post;
/* props array should look like this
$props = array(
"names" => array("SITE_TITLE", "SITE_URL"),
"titles" => array("Site Title", "Yours Site URL"),
"types" => array("textbox", "checkbox"),
can be 'textbox', 'checkbox', default is 'textbox'
);
*/
$this->filename = $filename;
$this->props = $props;
$this->prefix = $prefix;
$this->confvar = $confvar;
if(file_exists($filename)){
$this->load_file();
}
else {
out( "conf file $filename doesn't exits. Creating one ..." );
//create file
if(! $file = fopen($filename, "w") ){
error_here(1, "cant open file for reading");
return;
}
if(! $file = chmod($filename, 666) ){
error_here(1, "cant chmod file to 666");
return;
}
}
if(isset($post['action']) && $post['action'] == 'confsave')
if( $PERM['SETTINGS'] )
$this->save();
else
out( 'Sorry, this action is disabled
' );
}
function load_file(){
if(file_exists($this->filename) ){
include($this->filename);
}
else {
error_here(1, "cannot load file as it doesnt exist!");
return;
}
$num_props = count($this->props['names']);
for($i = 0; $i < $num_props; $i++){
$pname = $this->props['names'][$i];
$this->props['values'][$i] = ${$this->confvar}["$pname"];
}
}
function save(){
$this->grab_data();
$num_props = count($this->props['names']);
$line = "\n";
for($i = 0; $i < $num_props; $i++){
$line .= "\$" . $this->confvar . "[\"" . $this->props["names"][$i] . "\"] = \"" . $this->props["values"][$i] . "\";\n";
}
$line .= "?>";
if(! $file = fopen($this->filename, "w") ){
error_here(1, "cant open file for writing");
return;
}
fwrite($file, $line);
if(! fclose($file) ){
error_here(1, "cant close file after writing");
return;
}
$this->load_file();
}
function grab_data(){
global $HTTP_POST_VARS;
$num_props = count($this->props['names']);
for($i = 0; $i < $num_props; $i++){
if( isset($HTTP_POST_VARS['mwconf_' . $this->props['names'][$i]]) ){
$posted_value = $HTTP_POST_VARS['mwconf_' . $this->props['names'][$i]];
switch( $this->props['types'][$i] ){
case 'textbox':
$this->props['values'][$i] = $posted_value;
break;
case 'checkbox':
if( $posted_value == 'on')
$this->props['values'][$i] = 1;
else
$this->props['values'][$i] = 0;
break;
default:
$this->props['values'][$i] = $posted_value;
break;
}
}
else { // value not posted
if( $this->props['types'][$i] == 'checkbox' )
$this->props['values'][$i] = 0;
}
}
}
function edit(&$tpl, $tplfile = 'mwconf.tpl'){
global $admin_conf;
$loop = array();
$tpl->set_file('main', $tplfile);
$num_props = count($this->props['names']);
for($i = 0; $i < $num_props; $i++){
$pname = $this->props['names'][$i];
$pvalue = $this->props['values'][$i];
$defaults = $this->props['defaults'][$i];
switch( $this->props['types'][$i] ){
case 'select':
$edit_pvalue = "';
break;
case 'textbox':
$edit_pvalue = "";
break;
case 'checkbox':
$edit_pvalue = "";
break;
}
if( ($this->prefix) && (! ereg("^$this->prefix", $this->props['names'][$i])) )
continue;
$loop[$i] = array(
'PNAME' => $pname,
'PTITLE' => $this->props['titles'][$i],
'EDIT_PVALUE' => $edit_pvalue,
);
}
$tpl->set_loop('props', $loop);
return $tpl->process('out', 'main', 1);
}
}
?>
// TODO:
// Implement multiconditional selects
class mwDataFile{
var $dname; //without extension
var $data_file;
var $num;
var $item_len;
var $max;
var $limit;
function mwDataFile($dname, $names, $lens, $mode = ''){
$this->dname = $dname;
$this->data_file = new mwFile( $dname . '.dat' );
//set structure
$this->num = count($names);
$start = 0;
for( $i = 0; $i < $this->num; $i++ ){
$this->struct[$i] = array( $names[$i], $start, $lens[$i] );
$start += $lens[$i];
}
$this->item_len = $start;
$this->max = ($this->data_file->size())/($this->item_len);
$this->limit = 1000; //recommended max size, after that get_new_id will search for empty slots
if($mode && $this->data_file->exists()){
$this->data_file->open($mode);
}
}
function quit(){
$this->data_file->close();
}
function add($node){ //new node
$node['_id'] = $this->get_new_id();
$this->save( $node['_id'], $node);
$this->max = $this->max() + 1;
return $node['_id'];
}
function save($id, $node){
$string = '';
for( $i = 0; $i < $this->num; $i++ ){
$pname = $this->struct[$i][0];
$plen = $this->struct[$i][2];
if( strlen($node[$pname]) <= $plen ) // length okay, pad with spaces
$string .= str_pad( $node[$pname], $plen, ' ');
else{
echo "Warning: $pname length is longer that allowable $plen. Trimming to $plen ...
";
$string .= substr( $node[$pname], 0, $plen);
}
}
$offset = $this->item_len * ($id - 1);
$this->data_file->insert($offset, $string);
}
function get($id){
//returns $node array
$node = array();
$offset = $this->item_len * ($id - 1);
$string = $this->data_file->get_string($offset, $this->item_len);
if( ! trim($string) ) //empty
return array();
for( $i = 0; $i < $this->num; $i++ ){
$pname = $this->struct[$i][0];
$pstart = $this->struct[$i][1];
$plen = $this->struct[$i][2];
$node[ $pname ] = trim( substr( $string, $pstart, $plen) );
}
return $node;
}
function max(){
return $this->max;
}
function get_where($arg_list = array()){
//first coming 'AND' or 'OR'
//$arg_list is (pname, value) x n times
//returns number of items
$arr = array();
if( $arg_list ){ //search conditions are specified
$how = array_shift($arg_list);
$conditions = array();
$cond_num = count($arg_list)/2;
$found = 0;
//fill in conditions data
for($j = 0; $j < $cond_num; $j++){
$pname = $arg_list[2 * $j];
$pvalue = $arg_list[2 * $j + 1];
$pvalue = strtolower($pvalue);
//getting offset and length
if($pname == 'all'){ //search in all the data
$pstart = 0;
$plen = $this->item_len;
$found = 1;
}
else{
for( $i = 0; $i < $this->num; $i++ ){
if($this->struct[$i][0] == $pname){
$pstart = $this->struct[$i][1];
$plen = $this->struct[$i][2];
$found = 1;
break;
}
}
}
if(! $found)
echo "WARNING: cannot find property name $pname!
";
$conditions[ $j ]['pname'] = $pname;
$conditions[ $j ]['pvalue'] = $pvalue;
$conditions[ $j ]['pstart'] = $pstart;
$conditions[ $j ]['plen'] = $plen;
}
//traversing items
for( $id = 1; $id <= $this->max(); $id++ ){
$offset = $this->item_len * ($id - 1);
$bad = 0;
//checking conditions
for($j = 0; $j < $cond_num; $j++){
$pstart = $conditions[ $j ]['pstart'];
$plen = $conditions[ $j ]['plen'];
$val = $conditions[ $j ]['pvalue'];
//new - first parse the $val string, which in first letter contains =, >, <, % or !
$cond = '';
$cond = substr($val, 0, 1);
$val = substr($val, 1);
$infile = trim($this->data_file->get_string($offset + $pstart, $plen));
$infile = strtolower($infile);
switch($cond){
case '>':
if( $infile <= $val) // bad
$bad++;
break;
case '<':
if( $infile >= $val) // bad
$bad++;
break;
case '%': // LIKE condition
if( ! preg_match("/$val/", $infile) ) // bad
$bad++;
break;
case '=':
if( $infile != (string) $val) // bad
$bad++;
break;
case '!':
if( $infile == (string) $val) // bad
$bad++;
break;
default:
if( $infile != (string) $val) // bad
$bad++;
}
}
if( ($how == 'AND') && ($bad == 0) )// found
$arr[] = $this->get($id);
if( ($how == 'OR') && ($bad != $cond_num) )// found
$arr[] = $this->get($id);
}
}
else{ // no condition is specified
for( $id = 1; $id <= $this->max(); $id++ ){
$offset = $this->item_len * ($id - 1);
if( trim( $this->data_file->get_string($offset, 1) ) ) // item exists
$arr[] = $this->get($id);
}
}
return $arr;
}
function count_where($arg_list = array()){
//first coming 'AND' or 'OR'
//$arg_list is (pname, value) x n times
//returns number of items
$count = 0;
if( $arg_list ){ //search conditions are specified
$how = array_shift($arg_list);
$conditions = array();
$cond_num = count($arg_list)/2;
$found = 0;
//fill in conditions data
for($j = 0; $j < $cond_num; $j++){
$pname = $arg_list[2 * $j];
$pvalue = $arg_list[2 * $j + 1];
$pvalue = strtolower($pvalue);
//getting offset and length
if($pname == 'all'){ //search in all the data
$pstart = 0;
$plen = $this->item_len;
$found = 1;
}
else{
for( $i = 0; $i < $this->num; $i++ ){
if($this->struct[$i][0] == $pname){
$pstart = $this->struct[$i][1];
$plen = $this->struct[$i][2];
$found = 1;
break;
}
}
}
if(! $found)
echo "WARNING: cannot find property name $pname!
";
$conditions[ $j ]['pname'] = $pname;
$conditions[ $j ]['pvalue'] = $pvalue;
$conditions[ $j ]['pstart'] = $pstart;
$conditions[ $j ]['plen'] = $plen;
}
//traversing items
for( $id = 1; $id <= $this->max(); $id++ ){
$offset = $this->item_len * ($id - 1);
$bad = 0;
//checking conditions
for($j = 0; $j < $cond_num; $j++){
$pstart = $conditions[ $j ]['pstart'];
$plen = $conditions[ $j ]['plen'];
$val = $conditions[ $j ]['pvalue'];
//new - first parse the $val string, which in first letter contains =, >, <, % and !
$cond = '';
$cond = substr($val, 0, 1);
$val = substr($val, 1);
$infile = trim($this->data_file->get_string($offset + $pstart, $plen));
$infile = strtolower($infile);
switch($cond){
case '>':
if( $infile <= $val) // bad
$bad++;
break;
case '<':
if( $infile >= $val) // bad
$bad++;
break;
case '%': // LIKE condition
if( ! preg_match("/$val/", $infile) ) // bad
$bad++;
break;
case '=':
if( $infile != (string) $val) // bad
$bad++;
break;
case '!':
if( $infile == (string) $val) // bad
$bad++;
break;
default:
if( $infile != (string) $val) // bad
$bad++;
}
}
if( ($how == 'AND') && ($bad == 0) )// found
$count++;
if( ($how == 'OR') && ($bad != $cond_num) )// found
$count++;
}
}
else{ // no condition is specified
for( $id = 1; $id <= $this->max(); $id++ ){
$offset = $this->item_len * ($id - 1);
if( trim( $this->data_file->get_string($offset, 1) ) ) // item exists
$count++;
}
}
return $count;
}
function drop(){
// echo 'dropping ' . $this->data_file->filename;
$this->data_file->close();
if( ! $this->data_file->unlink() )
echo 'Cannot delete file ' . $this->data_file->filename . '';
}
function delete($id){
$offset = $this->item_len * ($id - 1);
$string = str_repeat(' ', $this->item_len);
$this->data_file->insert($offset, $string);
}
function get_new_id(){
$max = ($this->data_file->size())/($this->item_len);
if($max < $this->limit)
return $max + 1;
for($id = 1; $id < $max+1; $id++){
$offset = $this->item_len * ($id - 1);
if(! trim($this->data_file->get_string($offset, 1)) ){// found free slot
return $id;
}
}
return $max + 1;
}
}
?>
class mwEdit {
var $filename;
var $path;
var $full_filename;
var $description;
var $status;
function mwEdit($filename, $description = '', $path = ''){
global $PERM, $post;
$this->filename = $filename;
$this->description = $description;
$this->path = $path;
if( $path)
$full_filename = $path . $filename;
else
$full_filename = $filename;
$this->full_filename = $full_filename;
if(isset($post['action']) && $post['action'] == 'editsave'){
if( $PERM['TEMPLATES'] )
$this->save();
else
out( 'Sorry, this action is disabled
' );
}
if( file_exists($full_filename) ){
$this->load_file();
}
else {
out( "File $full_filename doesn't exits. Creating one ..." );
//create file
if(! $file = fopen($full_filename, "w") ){
error_here(1, "cant open file $full_filename for reading");
return;
}
if(! $file = chmod($full_filename, 666) ){
error_here(1, "cant chmod file $full_filename to 666");
return;
}
$this->status = "File created";
}
}
function load_file(){
if(! $file = fopen($this->full_filename, "r") ){
error_here(1, "cant open file $this->full_filenamefor reading");
return;
}
$this->content = "";
$this->content = fread ($file, filesize($this->full_filename));
if(! fclose($file) ){
error_here(1, "cant close file $this->full_filename after reading");
return;
}
if( (! isset($this->status)) || (! $this->status) )
$this->status = "File loaded";
}
function save(){
global $HTTP_POST_VARS;
$posted_filename = stripslashes($HTTP_POST_VARS['mwedit_fname']);
if( $posted_filename && ($this->filename != $posted_filename) ){
$this->filename = $posted_filename;
$this->full_filename = $this->path . $this->filename;
}
$this->grab_data();
if(! $file = fopen($this->full_filename, "w") ){
error_here(1, "cant open file $this->full_filename for writing");
return;
}
fwrite($file, $this->content);
if(! fclose($file) ){
error_here(1, "cant close file $this->full_filename after writing");
return;
}
$this->status = "File saved";
}
function grab_data(){
global $HTTP_POST_VARS;
$this->content = stripslashes($HTTP_POST_VARS['mwedit_content']);
}
function edit(&$tpl, $tplfile = 'mwedit.tpl', $pholders = array()){
global $CONF;
$tpl->set_file('main', $tplfile);
$tpl->set_var('FNAME', $this->filename);
$tpl->set_var('FDESC', $this->description);
$tpl->set_var('FSTATUS', $this->status);
$tpl->set_var('FCONTENT', htmlspecialchars($this->content));
$tpl->set_var('TXT_WIDTH', $CONF['AV_TXT_TEMPL_WIDTH']);
$tpl->set_var('TXT_HEIGHT', $CONF['AV_TXT_TEMPL_HEIGHT']);
$pholders_loop = array();
while(list($pholder, $pholder_desc) = each($pholders)){
$pholders_loop[] = array(
'PHOLDER' => $pholder,
'PHOLDER_DESC' => $pholder_desc,
);
}
if( ! $pholders_loop ){
$pholders_loop[] = array(
'PHOLDER' => 'None',
'PHOLDER_DESC' => '',
);
}
$tpl->set_loop('pholders', $pholders_loop);
return $tpl->process('out', 'main', 1);
}
}
?>
class mwEncryptor {
var $key;
function mwEncryptor($key = ''){
$this->key = $key;
}
function encrypt($data){
$out = '';
if( strlen($this->key)>0 ){ // real encryption
$current_key = md5($this->key);
$key_len = strlen($current_key);
$data_len = strlen($data);
$iterations = ceil( $data_len / $key_len);
for($i = 0; $i < $iterations; $i++){
$out .= substr($data, $i * $key_len, $key_len) ^ $current_key;
$current_key = md5($current_key);
}
}
else { //hashing - for passwords
$out = md5($data);
}
return $out;
}
function decrypt($data){
$out = '';
$current_key = md5($this->key);
$key_len = strlen($current_key);
$data_len = strlen($data);
$iterations = ceil( $data_len / $key_len);
for($i = 0; $i < $iterations; $i++){
$out .= substr($data, $i * $key_len, $key_len) ^ $current_key;
$current_key = md5($current_key);
}
return $out;
}
}
?>
class mwFile {
var $err;
var $filename;
var $fh; //file handle
function mwFile($filename, $dont_create = 0){
$this->filename = $filename;
if( ! $dont_create ){
if(! file_exists($this->filename) ){//attempt to create file
if( ! file_exists( dirname($this->filename) )){ //attempt to create directory
if( ! $this->create_path( dirname($this->filename) ) ){
return;
}
}
$this->open('a');
$this->close();
}
}
return 1;
}
function create_path($path){
$ok = 0;
if(! file_exists( dirname($path) )){
$ok = $this->create_path( dirname($path) );
}
if( mkdir($path, 0777) ){
chmod($path, 0777);
$ok = 1;
}
else{
echo "Failed to create $path directory!
";
return 0;
}
return $ok;
}
function size(){
if( $this->exists() )
return filesize($this->filename);
else
return 0;
}
function exists(){
return file_exists($this->filename);
}
function mtime(){
return filemtime($this->filename);
}
function utime($time = 0){
if($time)
touch($this->filename, $time, $time);
else
touch($this->filename);
}
function unlink(){
return @unlink($this->filename);
}
function get_content(){
$was_opened = (isset($this->fh)) ? 1 : 0;
if(! $was_opened ){
$this->open('r');
}
$content = '';
$content = fread ($this->fh, filesize($this->filename));
if(! $was_opened )
$this->close();
return $content;
}
function set_content($content){
$was_opened = (isset($this->fh)) ? 1 : 0;
if(! $was_opened )
$this->open('w');
if(! $file = fopen($this->filename, 'w') ){
$this->err = "cant open file $this->filename for writing";
return 0;
}
fwrite($this->fh, $content);
if(! $was_opened )
$this->close();
return 1;
}
function insert($offset, $string){
// inserts $string at specified $offset
$string = strval($string);
$was_opened = (isset($this->fh)) ? 1 : 0;
if(! file_exists($this->filename) ){//attempt to create file
$this->open('a');
$this->close();
}
if(! $was_opened )
$this->open('r+');
fseek($this->fh, $offset);
if ( ! fwrite($this->fh, $string) ) {
print "Can't write \"$string\" to file $this->filename at";
return;
}
if(! $was_opened )
$this->close('r');
return 1;
}
function get_string($offset, $len){
$was_opened = (isset($this->fh)) ? 1 : 0;
if(! $was_opened )
$this->open('r');
fseek($this->fh, $offset);
$string = trim( fread($this->fh, $len) );
if(! $was_opened )
$this->close('r');
return $string;
}
function open($mode){ // mode - 'r', 'w', 'r+', 'a'
if(! $this->fh = fopen($this->filename, $mode) ){
echo "cant open file $this->filename for $mode mode.";
exit;
}
#echo "opening " . $this->filename ."
";
}
function close(){
if( ! isset($this->fh) )
return;
if(! fclose($this->fh) ){
echo "cant close file $this->filename.";
exit;
}
#echo "closing " . $this->filename ."
";
unset($this->fh);
}
}
?>
class mwlCategoryCount extends mwObject {
function mwlCategoryCount($id = -1){
$this->mwObject($id);
$this->set_property('_class', 'mwlCategoryCount');
$this->_prop_names();
}
}
class mwlCategory extends mwObject {
function mwlCategory($id = -1){
$this->mwObject($id);
$this->set_property('_class', 'mwlCategory');
$this->set_property('_parent_class', 'mwlCategory');
$this->_prop_names();
}
function delete(){
global $adaptor;
$id = $this->get_property('_id');
//delete child subcategories and questions
$cats = $adaptor->retrieve_where('mwlCategory', "parent_id=$id");
while(list($key, $obj) = each($cats))
$obj->delete();
$links = $adaptor->retrieve_where('mwlLink', "parent_id=$id");
while(list($key, $obj) = each($links))
$obj->delete(1, 'Parent category has been deleted');
mwObject::delete();
}
function edit( $buttons = array('update') ){
global $adaptor, $tpl, $HTTP_SERVER_VARS;
$id = $this->get_property('_id');
$tpl->set_file('mwlcategory', 'admin_mwlcategory.tpl', 1);
// $buttons = array('update');
// if( $id != -1)
// $buttons[] = 'delete';
$tpl->set_var('MWOBJECT', mwObject::edit( $buttons ));
$tpl->set_var('MWOID', $id);
$tpl->set_var('ADMIN_URL', $HTTP_SERVER_VARS['PHP_SELF']);
if($id != -1){ //existing category or root, don't show children for a new one
//showing add toolbar
$tpl->process('ADD_CAT', 'add_cat');
if($id == 0) // don't allow to add links just in the root
$tpl->set_var('ADD_LINK', '');
else
$tpl->process('ADD_LINK', 'add_link');
//Showing subcategories
$objects = $adaptor->retrieve_where('mwlCategory', "parent_id=$id");
uasort($objects, 'cmp_title');
if(count($objects)){
while(list($key, $obj) = each($objects)){
$subcat_loop[] = array(
'CHILD_CAT_ID' => $obj->get_property('_id'),
'CHILD_CAT_TITLE' => $obj->get_property('title'),
'CHILD_CAT_COUNT' => $obj->get_count(),
);
}
$tpl->set_loop('subcats', $subcat_loop);
$tpl->process('SHOW_SUBCATS', 'exist_subcats', 1);
}
else {
$tpl->process('SHOW_SUBCATS', 'no_subcats');
}
//Showing links
$objects = $adaptor->retrieve_where('mwlLink', "parent_id=$id AND to_approve=0");
uasort($objects, 'cmp_title');
if(count($objects)){
while(list($key, $obj) = each($objects)){
$quest_loop[] = array(
'CHILD_QUEST_ID' => $obj->get_property('_id'),
'CHILD_QUEST_TITLE' => $obj->get_property('title'),
);
}
$tpl->set_loop('subquestions', $quest_loop);
$tpl->process('SHOW_QUESTS', 'exist_quests', 1);
}
else {
if($id == 0) // don't tell about clicking on Add Link button for root
$tpl->set_var('SHOW_QUESTS', '');
else
$tpl->process('SHOW_QUESTS', 'no_quests');
}
$tpl->process('CHILDREN', 'children');
}
else {
$tpl->set_var('CHILDREN', '');
}
return $tpl->process('out', 'mwlcategory');
}
function get_num_view_pages(){
global $adaptor, $CONF;
$id = $this->get_property('_id');
$count = $adaptor->count_where('mwlLink', "parent_id=$id AND to_approve=0");
if( $count )
return ceil( $count / (float)$CONF['GEN_LINKS_PER_PAGE'] );
else
return 1;
}
function view(&$tpl, $npage = 1, $html_ver = 0){
global $adaptor, $HTTP_SERVER_VARS, $navpage, $CONF;
$index_path = '';
$subcats_per_row = 2;
$subcat_percent_width = round(100 / $subcats_per_row);
$id = $this->get_property('_id');
if($id == 0){ // INDEX PAGE
if($html_ver)
$index_path = '../';
$tpl->set_file('content', 'view_category.tpl', 1);
$tpl->set_var('ID', $id);
// setting path
$tpl->set_var('BLOCK_CAT_PATH', '' );
// setting description
$tpl->set_var('BLOCK_CAT_DESCRIPTION', '' );
// setting subcats
//populate subcats
$objects = $adaptor->retrieve_where('mwlCategory', "parent_id=$id");
uasort($objects, 'cmp_title');
$count = count($objects);
$subcategories = '';
$i = 0;
foreach( $objects as $obj ){
if( $obj ){
$i++;
if( $i == 1)
$subcategories .= '
';
if( $i % $subcats_per_row == 1 ) // first item in row
$subcategories .= '';
$subcategories .= "| " . $obj->subcat_view( $tpl, $html_ver ) . ' | ';
if( $i % $subcats_per_row == 0 ) // last item in row
$subcategories .= '
';
}
}
if( $subcategories ){
$subcategories .= '
';
$tpl->set_var( 'CAT_SUBCATEGORIES', $subcategories );
$tpl->process( 'BLOCK_CAT_SUBCATEGORIES', 'block_cat_subcategories' );
}
else {
$tpl->set_var( 'BLOCK_CAT_SUBCATEGORIES', '' );
}
$tpl->set_var( 'BLOCK_CAT_SUBCATEGORIES_HEADER', '' );
// setting links
$tpl->set_var('BLOCK_CAT_LINKS', '' );
$tpl->set_var('BLOCK_CAT_LINKS_HEADER', '' );
}
//////////////////
// NON INDEX PAGE
else {
$tpl->set_file('content', 'view_category.tpl', 1);
$tpl->set_file('link', 'view_link.tpl', 1);
$tpl->set_file('pager', 'view_pager.tpl', 1);
$tpl->set_var('ID', $id);
// setting path
if($html_ver){
$tpl->set_var('CAT_PATH', $this->get_path("cat{ID}.html", 1) );
$index_path = '../';
}
else{
$tpl->set_var('CAT_PATH', $this->get_path($HTTP_SERVER_VARS['PHP_SELF'] . '?id={ID}') );
$index_path = './';
}
$tpl->process( 'BLOCK_CAT_PATH', 'block_cat_path' );
// setting description
if( $this->get_property('description') ){
$tpl->set_var('CAT_DESCRIPTION', $this->get_property('description'));
$tpl->process('BLOCK_CAT_DESCRIPTION', 'block_cat_description' );
}
else{
$tpl->set_var('BLOCK_CAT_DESCRIPTION', '' );
}
// setting subcats
//populate subcats
$objects = $adaptor->retrieve_where('mwlCategory', "parent_id=$id");
uasort($objects, 'cmp_title');
$count = count($objects);
$subcategories = '';
$i = 0;
foreach( $objects as $obj ){
if( $obj )
$i++;
if( $i == 1)
$subcategories .= '';
if( $i % $subcats_per_row == 1 ) // first item in row
$subcategories .= '';
$subcategories .= "| " . $obj->subcat_view( $tpl, $html_ver ) . ' | ';
if( $i % $subcats_per_row == 0 ) // last item in row
$subcategories .= '
';
}
if( $subcategories ){
$subcategories .= '
';
$tpl->set_var( 'CAT_SUBCATEGORIES', $subcategories );
$tpl->process( 'BLOCK_CAT_SUBCATEGORIES', 'block_cat_subcategories' );
$tpl->process( 'BLOCK_CAT_SUBCATEGORIES_HEADER', 'block_cat_subcategories_header' );
}
else {
$tpl->set_var( 'BLOCK_CAT_SUBCATEGORIES', '' );
$tpl->set_var( 'BLOCK_CAT_SUBCATEGORIES_HEADER', '' );
}
// setting links
//populate links
$objects = $adaptor->retrieve_where('mwlLink', "parent_id=$id AND to_approve=0");
uasort($objects, 'cmp_hits');
// setting pager
if( count($objects) > $CONF['GEN_LINKS_PER_PAGE'] ){ // need paging
$splitter = new mwSplitter($tpl, $objects, $CONF['GEN_LINKS_PER_PAGE']);
$splitter->set_page($npage);
if($html_ver)
$tpl->set_var('PAGER', $splitter->navigation_view("cat$id" . "_page{PAGE_NUM}.html", 1, "cat$id.html"));
else
$tpl->set_var('PAGER', $splitter->navigation_view($HTTP_SERVER_VARS['PHP_SELF'] . "?id=$id&navpage={PAGE_NUM}"));
$tpl->process( 'BLOCK_PAGER', 'block_pager' );
$objects =& $splitter->return_items();
}
else { // one page
$tpl->set_var( 'BLOCK_PAGER', '' );
}
// setting links
$links = '';
while(list($key, $obj) = each($objects)){
$links .= $obj->view($tpl, 0, $html_ver, $index_path);
}
if( $links ){
$tpl->set_var('CAT_LINKS', $links);
$tpl->process('BLOCK_CAT_LINKS', 'block_cat_links' );
$tpl->process('BLOCK_CAT_LINKS_HEADER', 'block_cat_links_header' );
}
else {
$tpl->set_var('BLOCK_CAT_LINKS', '' );
$tpl->set_var('BLOCK_CAT_LINKS_HEADER', '' );
}
}
$tpl->set_var('HOME_LINK', $index_path);
$tpl->set_var('NEW_LINK', $index_path.'ldnew.php');
$tpl->set_var('SUBMIT_LINK', $index_path.'ldsubmit.php?pid='.$id);
$tpl->set_var('SEARCH_LINK', $index_path.'ldsearch.php');
$tpl->set_var('MODIFY_LINK', $index_path.'ldmodify.php');
$tpl->set_var('PAGE_TITLE', $this->get_property('title'));
$tpl->process('CONTENT', 'content', 1);
if($html_ver)
return $tpl->process('out', 'main');
else
echo $tpl->process('out', 'main');
}
////////////////////////////////////////////////
function subcat_view(&$tpl, $html_ver = 0){
global $adaptor, $CONF;
$out = '';
$id = $this->get_property('_id');
$tpl->set_file('subcat', 'view_subcategory.tpl', 1);
// setting URL
if($html_ver)
$tpl->set_var('SUBCAT_URL', 'cat'.$id.'.html');
else
$tpl->set_var('SUBCAT_URL', '?id='.$id);
// setting title
$tpl->set_var('SUBCAT_TITLE', $this->get_property('title') );
// setting count
$tpl->set_var('SUBCAT_COUNT', $this->get_count() );
// okay, setting the link block - title with url and count
$tpl->process('BLOCK_SUBCAT_LINK', 'block_subcat_link');
// setting description
if( $this->get_property('description') ){
$tpl->set_var('SUBCAT_DESCRIPTION', $this->get_property('description') );
$tpl->process('BLOCK_SUBCAT_DESCRIPTION', 'block_subcat_description');
}
else {
$tpl->set_var('BLOCK_SUBCAT_DESCRIPTION', '' );
}
// setting links to subsubcategories
$max_subsubcats = 3; // after that number the ... will be shown
$subsubcats = '';
if( $CONF['GEN_SHOW_SUBCATS_INDEX'] ){
//get subcat subcats
$objects = $adaptor->retrieve_where('mwlCategory', "parent_id=$id");
uasort($objects, 'cmp_title');
$c = count($objects);
for($i = 0; $i < $c; $i++){
if( $i > $max_subsubcats-1 ){
$subsubcats .= '...';
break;
}
$obj = $objects[$i];
$subsubcats .= $obj->subsubcat_view($tpl, $html_ver);
}
}
if( $subsubcats ){
$tpl->set_var('SUBCAT_SUBCATEGORIES', $subsubcats);
$tpl->process('BLOCK_SUBCAT_SUBCATEGORIES', 'block_subcat_subcategories');
}
else {
$tpl->set_var('BLOCK_SUBCAT_SUBCATEGORIES', '');
}
// output
$out = $tpl->process('out', 'subcat', 1);
// free memory
$tpl->drop_var('subcat');
return $out;
}
function subsubcat_view(&$tpl, $html_ver = 0){
global $adaptor;
$out = '';
$id = $this->get_property('_id');
$tpl->set_file('subsubcat', 'view_subsubcategory.tpl');
// setting URL
if($html_ver)
$tpl->set_var('SUBSUBCAT_URL', 'cat'.$id.'.html');
else
$tpl->set_var('SUBSUBCAT_URL', '?id='.$id);
// setting title
$tpl->set_var('SUBSUBCAT_TITLE', $this->get_property('title') );
// setting count
$tpl->set_var('SUBSUBCAT_COUNT', $this->get_count() );
// output
$out = $tpl->process('out', 'subsubcat');
// free memory
$tpl->drop_var('subsubcat');
return $out;
}
function recalc_count( $skip_parent = 0){
global $adaptor;
$id = $this->get_property('_id');
// echo "calculating count for $id
";
$count = $adaptor->count_where('mwlLink', "parent_id=$id AND to_approve=0");
//this will also count links in child directories
$child_cats = $adaptor->retrieve_where('mwlCategory', "parent_id=$id");
foreach( $child_cats as $cat){
$count += $cat->get_count();
}
$catcount = new mwlCategoryCount( $id );
$catcount->set_property('count', $count);
$catcount->store();
if( ! $skip_parent ){
$this->load();
$pid = $this->get_property('parent_id');
if( $pid > 0 ){
$parent = new mwlCategory( $pid );
$parent->recalc_count();
}
}
return $count;
}
function get_count(){
$id = $this->get_property('_id');
$catcount = new mwlCategoryCount( $id );
$catcount->load();
$count = $catcount->get_property('count');
if( ! $count && $count != '0' )// calculate
$count = $this->recalc_count( 1 );
return $count;
}
function get_tree($force_expansion = 0, $ignore_noncats = 0, $not_root = 0){
global $adaptor;
$id = $this->get_property('_id');
//$tree is (id, title, 1(is_cat), children_array)
//children array is an array of $tree of children
$tree = array($id, $this->get_property('title'), 1, array());
//don't load children if this's not root (respectively) and expanded is not set
//anyway continue if force_expansion is set
if((!$force_expansion) && $not_root && (! $this->get_property('expanded')))
return $tree;
// show subcategories
$objects = $adaptor->retrieve_where('mwlCategory', "parent_id=$id");
while(list($key, $obj) = each($objects)){
$tree[3][] = $obj->get_tree($force_expansion, $ignore_noncats, 1);
}
if($ignore_noncats) //dont show non categories questions
return $tree;
// skipped: don't get questions
return $tree;
}
}
?>
class mwlHits extends mwObject{
var $id;
var $hits;
function mwlHits($id, $skip_load = 0){
$this->mwObject($id);
$this->set_property('_class', 'mwlHits');
$this->_prop_names();
if( ! $skip_load )
$this->load();
}
function count(){
return ( $this->get_property('hits') ) ? $this->get_property('hits') : 0;
}
function set($v = 0){
$this->set_property('hits', $v);
$this->store();
}
function inc(){
$hits = $this->count();
$this->set($hits + 1);
}
function delete(){
global $adaptor;
$adaptor->delete($this);
}
}
class mwObject {
var $properties;
var $prop_names;
var $form;
var $keep_props;
var $shifter = " ";
function mwObject($id = -1){
$this->properties = array();
$this->prop_names = array();
if(isset($id)){
$this->set_property('_id', $id);
}
$this->keep_props = false;
}
function get_tree(){
return array($this->get_property('_id'), $this->get_property('title'));
}
function handle_action($post){
global $adaptor, $tpl, $PERM, $CONF, $HTTP_SERVER_VARS, $HTTP_POST_VARS;
$id = $this->get_property('_id');
if( isset($post['action']) )
$action = $post['action'];
else
return $this;
switch($action){
case 'update':
$new = 0;
if( $this->validate_input() ){
if( $this->get_property('_id') == -1)
$new = 1;
$this->store();
// recalc count for a new mwlCategory
if ( $new && $this->get_property('_class') == 'mwlCategory' ){
$this->recalc_count();
}
//recalculate count for parent mwlCategory if this is a new link added
if ( $new && $this->get_property('_class') == 'mwlLink' ){
$parent_id = $this->get_property('parent_id');
$cat = new mwlCategory($parent_id);
$cat->recalc_count();
}
// send email to user, if this is a mwlLink
if ( ($this->get_property('_class') == 'mwlLink') && $CONF['GEN_SEND_USER_NOTIFICATIONS'] ){
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
if( count($users2links) > 0){ //found user2link
$u2l = $users2links[0];
$uid = $u2l->get_property('uid');
$user = new mwlUser($uid);
$user->load();
$tpl->set_file('user_msg', 'email_update.tpl');
$tpl->set_var( 'USER_FULLNAME', $user->get_property('title') );
$tpl->set_var( 'LINK_ID', $id );
$tpl->set_var( 'CATEGORY', $this->get_path_plain_txt() );
$tpl->set_var( 'LINK_URL', $this->get_property('url') );
$tpl->set_var( 'LINK_TITLE', $this->get_property('title') );
$tpl->set_var( 'LINK_DESC', $this->get_property('description') );
$modify_url = 'http://' . $HTTP_SERVER_VARS['HTTP_HOST'] . dirname($HTTP_SERVER_VARS['PHP_SELF']) . '/ldmodify.php';
$tpl->set_var( 'MODIFY_URL', $modify_url );
$user_msg = $tpl->process('out', 'user_msg');
$out = process_msg( $user_msg );
send_email(
$user->get_property('email'),
'Link Department Pro',
$out['subj'],
$out['msg']
);
}
}
$this->reset_form();
$this->get_form();
if( $CONF['CHK_LINKS_AUTO_VALIDATE'] ){
// validate URL
// do nothing as this is demo
}
out('Saved');
}
else{
$this->keep_props = true; //don't reload entered properties
}
break;
case 'delete':
$id = $this->get_property('_id');
$parent_id = $this->get_property('parent_id');
$parent_class = $this->get_property('_parent_class');
if( $PERM['DELETE'] ){
if( $this->get_property('_class') == 'mwlLink' )
$this->delete(1);
else
$this->delete();
out( "Object with id=$id has been deleted.
" );
}
else
out ( 'Sorry, this action is disabled
' );
unset($this);
//now the deleted object becomes its parent
$this = $adaptor->get_obj($parent_id, $parent_class);
$this->get_form();
break;
case 'add':
break;
default:
out( "Don't have a handle for $action action!
" );
}
return $this;
}
function load(){
global $adaptor, $CONF, $post;
if( $this->keep_props )
return;
$id = $this->get_property('_id');
if($id == 0){ // root
$this->set_property('title', $CONF['GEN_SITE_TITLE']);
$this->set_property('expanded', 1);
}
elseif ($id > 0){ //existing object
if( ! ($adaptor->load($this)) )
return 0;
}
else{ //new object
$this->set_defaults();
if( isset($post['pid']) ){
$this->set_property( 'parent_id', $post['pid'] );
}
}
return 1;
}
function store(){
global $adaptor;
return $adaptor->store($this);
}
function delete(){
global $adaptor, $PERM;
$id = $this->get_property("_id");
$adaptor->delete($this);
}
function get_prop_names(){
return $this->prop_names;
}
function _prop_names(){
global $schema;
$props = array();
$ps = $schema[$this->get_property('_class')]['properties'];
while( list($pname, $parray) = each($ps) ){
$props[] = $pname;
}
$this->prop_names = $props;
}
function get_property($pname){
// if(! isset($this->properties["$pname"]) ){
// $this->load();
// }
if(! isset($this->properties["$pname"]) )
return '';
// return $this->properties["$pname"];
return htmlspecialchars( $this->properties["$pname"] );
}
function set_property($pname, $pvalue, $encrypt = 0){
global $schema;
$pvalue = trim($pvalue);
$pvalue = stripslashes($pvalue);
$pvalue = ereg_replace("\r\n", "", $pvalue);
$pvalue = ereg_replace("\n", "", $pvalue);
// $pvalue = htmlentities($pvalue);
if( $pname == 'title' && strlen($pvalue) <= 0 ){
out( 'Cannot set the title to the blank value!' );
$pvalue = $this->get_property("$pname");
}
//process encrypted items
if( $encrypt ){
if( isset( $schema[$this->get_property('_class')]['properties']["$pname"] ) ){
$ps = $schema[$this->get_property('_class')]['properties']["$pname"]; //property data hash
if( isset($ps['encrypted']) && ($ps['encrypted']) ){
$enc = new mwEncryptor();
$pvalue = $enc->encrypt( $pvalue );
}
}
}
// $this->properties["$pname"] = $pvalue;
$this->properties["$pname"] = unhtmlentities($pvalue);
}
function validate_input(){
global $adaptor;
if(! $this->form->submitted() )
return 0;
$bad = 0;
$count = count( $this->form->elements );
for($i = 0; $i < $count; $i++){
$el = & $this->form->elements[$i];
$el->grab_value();
if( $el->validate() ){ // element validated
// validate user email on uniqueness
if( $this->get_property('_class') == 'mwlUser' && $el->get_pname() == 'email' ){
$uid = $this->get_property('_id');
$count = $adaptor->count_where('mwlUser', "email=" . $el->get_value() . " AND _id!$uid");
if( $count > 0 ){
$this->set_property( $el->get_pname(), $el->get_value(), 1 );
$bad++;
$el->set_error( 'This email is already registered' );
}
}
$this->set_property( $el->get_pname(), $el->get_value(), 1 );
}
else {
if( $el->get_value() ) // nevertheless set the value to display in form
$this->set_property( $el->get_pname(), $el->get_value(), 1 );
$bad++;
}
}
if( $bad )
return 0;
else
return 1;
}
function edit( $buttons = array('update'), $tpl_file='admin_mwobject.tpl', $clickable_path = 1 ){
global $adaptor, $schema, $tpl, $base_url;
if($buttons == 'default')
$buttons = array('update');
if($tpl_file == 'default')
$tpl_file = 'admin_mwobject.tpl';
$id = $this->get_property('_id');
if($id == 0) //skip for root
return '';
$path_tpl = '';
if( $clickable_path)
$path_tpl = $base_url . 'mwa=class:{PARENT_CLASS}__id:{ID}';
$tpl->set_var('PATH', $this->get_path($path_tpl));
$tpl->set_var('MWOID', $id);
$tpl->set_var('_CLASS', $this->get_property('_class'));
// now setting form
$el_count = count($this->form->elements);
for($i = 0; $i < $el_count; $i++){
$el = & $this->form->elements[$i];
$pname = $el->get_pname();
$el->set_value( $this->get_property("$pname") );
// check if it is a Bad Link
if( $el->get_pname() == 'url' && $this->get_property('_class') == 'mwlLink' ){
$bad_links = $adaptor->retrieve_where('mwlBadLink', "_id=$id");
if( count($bad_links) > 0 && ! $el->get_error() )
$el->set_error('In Bad Links list');
}
}
return $this->form->show($tpl, $buttons, $tpl_file);
}
function reset_form(){
unset($this->form);
// $this->get_form();
}
function add_to_form( $prop, $get_submitted = 0 ){
//a $prop element can be either a property name or an array itself
// if so then it looks like array(
// 'pname' => 'some_name',
// 'orig_class' => 'some_class', // from which class it originates
// 'orig_pname' => 'some_pname', // its name in the original class
// 'ps' => array() - property data hash that overrides $schema settings if any
global $schema, $HTTP_POST_VARS;
$id = $this->get_property('_id');
$ps = array();
if( is_array($prop) ){
$pname = $prop['pname'];
if( ! isset($prop['orig_class']) )
$prop['orig_class'] = $this->get_property('_class');
if( ! isset($prop['orig_pname']) )
$prop['orig_pname'] = $pname;
if( ! isset($prop['ps']) )
$prop['ps'] = array();
$ps = $schema[ $prop['orig_class'] ]['properties'][ $prop['orig_pname'] ]; //property data hash
while( list($k, $v) = each($prop['ps']) ){
$ps[$k] = $v; // overriding $schema settings
}
}
else{
$pname = $prop;
$ps = $schema[$this->get_property('_class')]['properties']["$pname"]; //property data hash
}
$hname = 'prop_' . $id . '_' . $pname;
if( $get_submitted ){
if( ! isset($HTTP_POST_VARS[$hname]) )
return;
}
else {
if( isset($ps['not_shown']) && ($ps['not_shown']) )
return;
}
$ctl_class = $ps['html_type'];
$title = ( $ctl_class == 'cwHidden') ? '' : $ps['html_title'];
if( ($prop == 'parent_id') && ($ctl_class == 'cwSelect') ){
$root = new mwlCategory(0);
$root->load();
$node = new mwNode($root->get_tree(1, 1));
if( $this->get_property('_class') == 'mwlCategory' ){
$fill = $node->get_select_fill( '', $this->get_property('_id') );
}
else
$fill = $node->get_select_fill( '' );
$ctl = & new $ctl_class($hname, $title, $fill, $this->get_property('parent_id'));
}
else{
$ctl = & new $ctl_class($hname, $title);
}
$ctl->set_pname($pname);
if( isset($ps['html_readonly']) && ($ps['html_readonly']) )
$ctl->set_readonly();
while( list($k, $v) = each($ps['html_views']) )
$ctl->set_view($k, $v);
// adding check for property length
$msg = 'Max length of ' . $pname . '
is ' . $ps['size'] . '.';
$re = '/^.{0,' . $ps['size'] . '}$/';
$ctl->add_check( $msg, $re );
// adding checks from schema.php
if( isset($ps['html_validate']) ){
foreach( $ps['html_validate'] as $arr)
$ctl->add_check( $arr[0], $arr[1] );
}
$this->form->add($ctl);
}
function set_form_id($id){
$this->form->set_id($id);
}
function get_form(){
//optionally can enter arguments
//a $props element can be an array itself
//if so then it looks like array(
// 'pname' => 'some_name',
// 'parent_class' => 'some_class',
// 'ps' => array() - property data hash which override $schema settings if any
global $schema;
if( isset($this->form) ){
return;
}
if( func_num_args() > 0 )
$prop_names = func_get_args();
else
$prop_names = $this->get_prop_names();
$this->form = new cwForm();
while( list($key, $prop) = each($prop_names) ){
$this->add_to_form( $prop );
}
}
function get_submitted_form(){
global $schema;
unset($this->form);
$this->form = new cwForm();
$prop_names = $this->get_prop_names();
while( list($key, $prop) = each($prop_names) )
$this->add_to_form( $prop, 1 );
}
function get_parents(){
// returns ref to array of object parent nodes up to root
global $ROOT_CLASS, $adaptor;
$parents = array();
if($this->get_property('_id') != 0){
$parent_id = $this->get_property('parent_id');
$parent_class = $this->get_property('_parent_class');
$parent = $adaptor->get_obj($parent_id, $parent_class);
$parent->load(array('parent_id', 'title'));
$parents = $parent->get_parents();
$parents[] = $parent;
}
return $parents;
}
function get_file_path(){
// returns consecutive file system paths for an html file
// example: 'autos/new/suv/index.html'
// replaces bad characters with '_'
$count = 0;
$collect_path = '';
$path = '';
$paths = array();
$parents = $this->get_parents();
$parents[] = $this;
while(list($key, $par) = each( $parents )){
if( ! $count++) // don't include the index page title
continue;
$par_title = $par->get_property('title');
$par_title = filesystem_ready($par_title);
if($count != 2) // don't include the starting / for the first dir
$path .= '/' . $par_title;
else
$path .= $par_title;
}
return $path;
}
function get_index_path(){
$path = '';
$count = count( $this->get_parents() );
for($i = 0; $i <= $count; $i++)
$path .= '../';
return $path;
}
function get_path_plain_txt(){
global $CONF, $tpl;
$out = '';
$parents = $this->get_parents();
for( $i = 0; $i < count($parents); $i++){
$par = $parents[$i];
if( $i )
$out .= ' ' . $CONF['GEN_PATH_SEP'] . ' ';
$out .= $par->get_property('title');
}
// while(list($key, $par) = each( $parents )){
// $par_title = $par->get_property('title');
// $out .= $par_title . $CONF['GEN_PATH_SEP'];
// }
return $out;
}
function get_path( $url_tmpl = '', $html_ver = 0, $index_path = '' ){
global $CONF, $tpl;
$tpl->set_file('path', 'view_path.tpl', 1);
$out = '';
$parents = $this->get_parents();
while(list($key, $par) = each( $parents )){
$par_id = $par->get_property('_id');
$par_class = $par->get_property('_class');
$par_title = $par->get_property('title');
if($url_tmpl){ //clickable
if($par_id != 0){ // NOT ROOT LINK
if( $html_ver ){
$url = str_replace("{ID}", "$par_id", "$url_tmpl");
}
else{
$url = str_replace("{ID}", "$par_id", "$url_tmpl");
$url = str_replace("{PARENT_CLASS}", "$par_class", "$url");
}
}
else{ // ROOT LINK
if( $html_ver )
$url = './';
else{
$url = str_replace("{ID}", "0", "$url_tmpl");
$url = str_replace("{PARENT_CLASS}", "$par_class", "$url");
}
}
$tpl->set_var('PATH_COMPONENT_URL', $index_path . $url);
$tpl->set_var('PATH_COMPONENT_TITLE', $par_title);
$out .= $tpl->process('BLOCK_PATH_COMPONENT', 'block_path_component_clickable') . $CONF['GEN_PATH_SEP'];
}
else {
$tpl->set_var('PATH_COMPONENT_TITLE', $par_title);
$out .= $tpl->process('BLOCK_PATH_COMPONENT', 'block_path_component_non_clickable') . $CONF['GEN_PATH_SEP'];
}
}
// add itself
$tpl->set_var('PATH_COMPONENT_TITLE', $this->get_property('title'));
$out .= $tpl->process('BLOCK_PATH_COMPONENT', 'block_path_component_non_clickable');
// free memory
$tpl->drop_var('path');
return $out;
}
function set_defaults(){
global $schema;
$prop_names = $this->get_prop_names();
while(list($key, $pname) = each($prop_names)){
$ps = $schema[$this->get_property('_class')]['properties']["$pname"]; //property data hash
if( isset($ps['default']) ){
$this->set_property("$pname", $ps['default']);
}
if( $ps['type'] == 'date' )
$this->set_property("$pname", time());
}
}
function dump(){
global $schema;
$prop_names = $this->get_prop_names();
while(list($key, $pname) = each($prop_names)){
$ps = $schema[$this->get_property('_class')]['properties']["$pname"]; //property data hash
echo "$pname = " . $this->get_property($pname) . "
";
}
}
function set_by_array($array){
foreach($array as $key => $value)
$this->set_property($key, $value);
}
function get_by_array(){
$r = array();
$prop_names = $this->get_prop_names();
while( list($key, $pname) = each($prop_names) ){
if( $pname == '_id') //skip _id not to be ovveriden
continue;
$r[$pname] = $this->get_property($pname);
}
return $r;
}
}
class mwSplitter{
var $items;
var $page;
var $page_size;
function mwSplitter(&$tpl, &$items, $page_size = 10){
global $HTTP_POST_VARS;
$this->tpl = $tpl;
$this->items = $items;
if( ! $page_size)
$page_size = 10;
$this->page_size = $page_size;
$this->set_page(1);
}
function navigation_view( $url_tmpl, $html_ver = 0, $html_first_page = '' ){
$out = '';
$this->tpl->set_file('pager', 'view_pager.tpl', 1);
for ( $i = 1; $i <= $this->get_num_pages(); $i++){
if($html_ver && $i == 1)
$page_url = $html_first_page;
else
$page_url = str_replace("{PAGE_NUM}", "$i", "$url_tmpl");
$this->tpl->set_var('PAGE_URL', $page_url);
// setting page number
$this->tpl->set_var('PAGE_NUM', $i);
// setting page block
if( $i == $this->get_page() )
$this->tpl->process('BLOCK_PAGE', 'block_current_page');
else
$this->tpl->process('BLOCK_PAGE', 'block_other_page');
$out .= $this->tpl->process('out', 'pager');
}
// free memory
$this->tpl->drop_var('pager');
return $out;
}
function get_num_pages(){
if($this->page_size == 'all')
return 1;
else {
if( count($this->items) > 0)
return ceil( count($this->items) / (float)$this->page_size );
else
return 1;
}
}
function set_page($page){
if($page > $this->get_num_pages() or $page <= 0) return FALSE;
$this->page = $page;
}
function get_page(){
return $this->page;
}
function &return_items(){
if($this->page_size == 'all')
return $this->items;
else
return array_slice($this->items, ($this->get_page()-1)*$this->page_size, $this->page_size);
}
}
?>
class mwlBadLink extends mwObject {
function mwlBadLink($id = -1){
$this->mwObject($id);
$this->set_property('_class', 'mwlBadLink');
$this->_prop_names();
}
}
class mwlLinkModified extends mwlLink {
function mwlLinkModified($id = -1){
$this->mwlLink($id);
$this->set_property('_class', 'mwlLinkModified');
$this->_prop_names();
}
function handle_action($post){
global $adaptor, $tpl, $CONF, $HTTP_POST_VARS, $HTTP_SERVER_VARS;
$id = $this->get_property('_id');
$orig_id = $this->get_property('orig_id');
if( isset($post['action']) )
$action = $post['action'];
else
return $this;
switch($action){
case 'approve':
$link = new mwlLink($orig_id);
$link->load();
if( $this->validate_input() ){
$data = $this->get_by_array();
$link->set_by_array( $data );
$link->store();
//recalculate count for parent mwlCategory
$parent_id = $link->get_property('parent_id');
$cat = new mwlCategory($parent_id);
$cat->recalc_count();
// send email to user
if ( $CONF['GEN_SEND_USER_NOTIFICATIONS'] ){
$id = $this->get_property('orig_id');
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
if( count($users2links) > 0){ //found user2link
$u2l = $users2links[0];
$uid = $u2l->get_property('uid');
$user = new mwlUser($uid);
$user->load();
$tpl->set_file('user_msg', 'email_modapproval.tpl');
$tpl->set_var( 'USER_FULLNAME', $user->get_property('title') );
$tpl->set_var( 'LINK_ID', $id );
$tpl->set_var( 'CATEGORY', $this->get_path_plain_txt() );
$tpl->set_var( 'LINK_URL', $this->get_property('url') );
$tpl->set_var( 'LINK_TITLE', $this->get_property('title') );
$tpl->set_var( 'LINK_DESC', $this->get_property('description') );
$modify_url = 'http://' . $HTTP_SERVER_VARS['HTTP_HOST'] . dirname($HTTP_SERVER_VARS['PHP_SELF']) . '/ldmodify.php';
$tpl->set_var( 'MODIFY_URL', $modify_url );
$user_msg = $tpl->process('out', 'user_msg');
$out = process_msg( $user_msg );
send_email(
$user->get_property('email'),
'Link Department Pro',
$out['subj'],
$out['msg']
);
}
}
$this->delete();
unset($this);
echo "Modification for link with id=$orig_id has been approved.";
return;
}
else{
$this->keep_props = true; //don't reload entered properties
}
return $this;
break;
case 'reject': // link modification rejected
// send email to user
if ( $CONF['GEN_SEND_USER_NOTIFICATIONS'] ){
$id = $this->get_property('orig_id');
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
if( count($users2links) > 0){ //found user2link
$u2l = $users2links[0];
$uid = $u2l->get_property('uid');
$user = new mwlUser($uid);
$user->load();
$tpl->set_file('user_msg', 'email_modrejection.tpl');
$tpl->set_var( 'USER_FULLNAME', $user->get_property('title') );
$tpl->set_var( 'LINK_ID', $id );
$tpl->set_var( 'CATEGORY', $this->get_path_plain_txt() );
$tpl->set_var( 'LINK_URL', $this->get_property('url') );
$tpl->set_var( 'LINK_TITLE', $this->get_property('title') );
$tpl->set_var( 'LINK_DESC', $this->get_property('description') );
$reject_reason = trim( $HTTP_POST_VARS['reject_reason' . $this->get_property('_id')]);
$reject_reason = ( strlen($reject_reason) > 0 ) ? $reject_reason : 'None';
$tpl->set_var( 'REJECT_REASON', $reject_reason );
$user_msg = $tpl->process('out', 'user_msg');
$out = process_msg( $user_msg );
send_email(
$user->get_property('email'),
'Link Department Pro',
$out['subj'],
$out['msg']
);
}
}
$this->delete();
unset($this);
echo "Modification for link with id=$orig_id has been rejected.";
return;
break;
default:
return mwObject::handle_action($post);
}
return $this;
}
function delete(){
mwObject::delete();
}
function edit( $buttons = array('update'), $clickable_path = 1 ){
global $adaptor, $tpl;
if($buttons == 'default')
$buttons = array('update');
$id = $this->get_property('orig_id');
$orig = new mwlLink($id);
$orig->get_form();
$orig->load();
$tpl->set_file('linkinfo', 'admin_linkinfo.tpl', 1);
$link_info_loop =
array(
array('TITLE' => 'Path', 'VALUE' => $orig->get_path() ),
array('TITLE' => 'Link Title', 'VALUE' => $orig->get_property('title') ),
array('TITLE' => 'URL', 'VALUE' => $orig->get_property('url') ),
array('TITLE' => 'Description', 'VALUE' => $orig->get_property('description') ),
);
$tpl->set_loop('link_info_loop', $link_info_loop );
return $tpl->process('out', 'linkinfo', 1) . mwObject::edit($buttons, 'default', $clickable_path);
}
}
class mwlLink extends mwObject {
function mwlLink($id = -1){
$this->mwObject($id);
$this->set_property('_class', 'mwlLink');
$this->set_property('_parent_class', 'mwlCategory');
$this->_prop_names();
}
function delete( $send_email = 0, $delete_reason = '' ){
global $adaptor, $CONF, $tpl, $HTTP_POST_VARS;
$id = $this->get_property('_id');
//delete hits
$hits = new mwlHits($id, 1);
$hits->delete();
// send email to user
if ( $send_email && $CONF['GEN_SEND_USER_NOTIFICATIONS'] ){
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
if( count($users2links) > 0){ //found user2link
$u2l = $users2links[0];
$uid = $u2l->get_property('uid');
$user = new mwlUser($uid);
$user->load();
$tpl->set_file('user_msg', 'email_delete.tpl');
$tpl->set_var( 'USER_FULLNAME', $user->get_property('title') );
$tpl->set_var( 'LINK_ID', $id );
$tpl->set_var( 'CATEGORY', $this->get_path_plain_txt() );
$tpl->set_var( 'LINK_URL', $this->get_property('url') );
$tpl->set_var( 'LINK_TITLE', $this->get_property('title') );
$tpl->set_var( 'LINK_DESC', $this->get_property('description') );
if( isset( $HTTP_POST_VARS['delete_reason' . $id] ) )
$delete_reason = trim( $HTTP_POST_VARS['delete_reason' . $id] );
$delete_reason = ( strlen($delete_reason) > 0 ) ? $delete_reason : 'None';
$tpl->set_var( 'DELETE_REASON', $delete_reason );
$user_msg = $tpl->process('out', 'user_msg');
$out = process_msg( $user_msg );
send_email(
$user->get_property('email'),
'Link Department Pro',
$out['subj'],
$out['msg']
);
}
}
//delete user2link
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
while(list($key, $u2l) = each($users2links))
$u2l->delete();
//delete modified link
$mod_links = $adaptor->retrieve_where('mwlLinkModified', "orig_id=$id");
while(list($key, $ml) = each($mod_links))
$ml->delete();
//delete bad link
$bad_links = $adaptor->retrieve_where('mwlBadLink', "_id=$id");
while(list($key, $bl) = each($bad_links))
$bl->delete();
//get parent_id to later recalculate count for parent mwlCategory
$parent_id = $this->get_property('parent_id');
mwObject::delete();
//recalculate count for parent mwlCategory
$cat = new mwlCategory($parent_id);
$cat->recalc_count();
}
function view( &$tpl , $show_path = 0, $html_ver = 0, $index_path = '', $php_path = ''){
//$show_path can be 0 to show no path, 1 to show text info, 2 to show clickable
global $HTTP_SERVER_VARS;
if( !$php_path)
$php_path = $index_path;
$id = $this->get_property('_id');
$url = $this->get_property('url');
// if($html_ver)
// $index_path = '../';
// else
// $index_path = '';
$tpl->set_var('OUT_LINK', $php_path.'ldout.php?id='.$id.'&to='.$url);
$tpl->set_var('LINK_ID', $id);
$tpl->set_var('LINK_TITLE', $this->get_property('title'));
$tpl->set_var('LINK_DESCRIPTION', $this->get_property('description'));
$tpl->set_var('LINK_URL', $url);
$tpl->set_var('LINK_DATE', date( "M j, Y", $this->get_property('date') ));
$hits = new mwlHits($id);
$tpl->set_var('LINK_HITS', $hits->count() );
unset($hits);
// setting path
if( $show_path ){
if($show_path == 1)
$tpl->set_var('LINK_PATH', $this->get_path() );
elseif($show_path == 2)
if( $html_ver )
$tpl->set_var('LINK_PATH', $this->get_path("cat{ID}.html", $html_ver, $index_path) );
else
$tpl->set_var('LINK_PATH', $this->get_path('index.php?id={ID}') );
$tpl->process('BLOCK_LINK_PATH', 'block_link_path');
}
else {
$tpl->set_var('BLOCK_LINK_PATH', '');
}
$tpl->process('BLOCK_LINK_INFO', 'block_link_info');
return $tpl->process('LINKS', 'link');
}
function view_plain( $html = 0 ){
if($html){
$sep = '
';
$b_start = '';
$b_end = '';
}
else {
$sep = "\n";
$b_start = '';
$b_end = '';
}
$text = '';
$text .= $b_start . "Path:" . $b_end . $sep . $this->get_path_plain_txt() . $sep;
$text .= $b_start . "Link Title:" . $b_end . $sep . $this->get_property('title') . $sep;
$text .= $b_start . "URL:" . $b_end . $sep . $this->get_property('url') . $sep;
$text .= $b_start . "Description:" . $b_end . $sep . $this->get_property('description') . $sep;
return $text;
}
function get_user( $id = 0 ){
global $adaptor;
$id = ( $id ) ? $id : $this->get_property('_id');
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
if( count($users2links) > 0){ //found user2link
$u2l = $users2links[0];
$uid = $u2l->get_property('uid');
$this_user = new mwlUser($uid);
$this_user->load();
$this->set_property( 'user_name', $this_user->get_property('title') );
$this->set_property( 'user_email', $this_user->get_property('email') );
}
}
function submit_form(){
global $tpl;
$tpl->set_file('link_submit', 'page_submit.tpl');
$tpl->set_var('SUBMIT_FORM',
''
);
$tpl->set_var('ID', 0);
$tpl->process('CONTENT', 'link_submit');
return $tpl->process('out', 'main');
}
function add_admin_fields(){
$id = $this->get_property('_id');
//adding hits
$this->add_to_form( array(
'pname' => 'hits',
'orig_pname' => 'hits',
'orig_class' => 'mwlHits',
'ps' => array(
'html_readonly' => 1,
),
)
);
$hits = new mwlHits($id);
$this->set_property('hits', $hits->count() );
unset($hits);
//adding username and useremail
$this->add_to_form( array(
'pname' => 'user_name',
'orig_pname' => 'title',
'orig_class' => 'mwlUser',
'ps' => array( 'html_readonly' => 1, 'html_validate' => array() ),
)
);
$this->add_to_form( array(
'pname' => 'user_email',
'orig_pname' => 'email',
'orig_class' => 'mwlUser',
'ps' => array( 'html_readonly' => 1, 'html_validate' => array() ),
)
);
}
function store(){
$id = $this->get_property('_id');
mwObject::store();
if($id == -1){ // new link, save 0 in hits for it
$id = $this->get_property('_id'); // now it has new id after mwObject::store()
$hits = new mwlHits($id, 1);
$hits->set(0);
}
return $this;
}
function handle_action($post){
global $adaptor, $CONF, $tpl, $set, $HTTP_POST_VARS, $HTTP_SERVER_VARS;
$id = $this->get_property('_id');
if( isset($post['action']) )
$action = $post['action'];
else
return $this;
switch($action){
case 'modify': //when user requests link modify
if( $this->validate_input() ){
$data = $this->get_by_array(); //new data
unset( $data['_id'] );
// check if we already have modification waiting
// if so then override it
$ms = $adaptor->retrieve_where('mwlLinkModified', "orig_id=$id");
if( count($ms) > 0 ) // modification exists
$mlink = $ms[0];
else
$mlink = new mwlLinkModified();
$mlink->set_by_array($data);
$mlink->set_property('orig_id', $id);
$mlink->store();
$msg = get_file_content( $set['main_dir'] . '/templates/msg_modapproval.tpl' );
out( $msg );
// echo "Link with id=$id waiting modification approval.";
}
else{
$this->keep_props = true; //don't reload entered properties
}
return $this;
break;
case 'approve':
if( $this->validate_input() ){
$this->set_property('to_approve', 0);
//update time
$this->set_property('date', time());
$this->store();
$id = $this->get_property('_id');
//recalculate count for parent mwlCategory
$parent_id = $this->get_property('parent_id');
$cat = new mwlCategory($parent_id);
$cat->recalc_count();
// send email to user
if ( $CONF['GEN_SEND_USER_NOTIFICATIONS'] ){
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
if( count($users2links) > 0){ //found user2link
$u2l = $users2links[0];
$uid = $u2l->get_property('uid');
$user = new mwlUser($uid);
$user->load();
$tpl->set_file('user_msg', 'email_approval.tpl');
$tpl->set_var( 'USER_FULLNAME', $user->get_property('title') );
$tpl->set_var( 'LINK_ID', $id );
$tpl->set_var( 'CATEGORY', $this->get_path_plain_txt() );
$tpl->set_var( 'LINK_URL', $this->get_property('url') );
$tpl->set_var( 'LINK_TITLE', $this->get_property('title') );
$tpl->set_var( 'LINK_DESC', $this->get_property('description') );
$modify_url = 'http://' . $HTTP_SERVER_VARS['HTTP_HOST'] . dirname($HTTP_SERVER_VARS['PHP_SELF']) . '/ldmodify.php';
$tpl->set_var( 'MODIFY_URL', $modify_url );
$user_msg = $tpl->process('out', 'user_msg');
$out = process_msg( $user_msg );
send_email(
$user->get_property('email'),
'Link Department Pro',
$out['subj'],
$out['msg']
);
}
}
unset($this);
out( "Link with id=$id has been approved." );
return;
}
else{
$this->keep_props = true; //don't reload entered properties
}
return $this;
break;
case 'reject':
$id = $this->get_property('_id');
// send email to user
if ( $CONF['GEN_SEND_USER_NOTIFICATIONS'] ){
$users2links = $adaptor->retrieve_where('mwlUser2Link', "lid=$id");
if( count($users2links) > 0){ //found user2link
$u2l = $users2links[0];
$uid = $u2l->get_property('uid');
$user = new mwlUser($uid);
$user->load();
$tpl->set_file('user_msg', 'email_rejection.tpl');
$tpl->set_var( 'USER_FULLNAME', $user->get_property('title') );
$tpl->set_var( 'CATEGORY', $this->get_path_plain_txt() );
$tpl->set_var( 'LINK_URL', $this->get_property('url') );
$tpl->set_var( 'LINK_TITLE', $this->get_property('title') );
$tpl->set_var( 'LINK_DESC', $this->get_property('description') );
$reject_reason = trim( $HTTP_POST_VARS['reject_reason' . $id]);
$reject_reason = ( strlen($reject_reason) > 0 ) ? $reject_reason : 'None';
$tpl->set_var( 'REJECT_REASON', $reject_reason );
$user_msg = $tpl->process('out', 'user_msg');
$out = process_msg( $user_msg );
send_email(
$user->get_property('email'),
'Link Department Pro',
$out['subj'],
$out['msg']
);
}
}
$this->delete();
out( "Link with id=$id has been rejected." );
unset($this);
return;
break;
case 'resethits':
$hits = new mwlHits($id);
$hits->set(0);
return $this;
break;
default:
return mwObject::handle_action($post);
}
return $this;
}
}
?>
class mwlUser2Link extends mwObject{
function mwlUser2Link($id = -1){
$this->mwObject($id);
$this->set_property('_class', 'mwlUser2Link');
$this->_prop_names();
}
}
class mwlCommunity extends mwObject{
function mwlCommunity(){
$this->mwObject(0);
$this->set_property('_class', 'mwlCommunity');
}
function load(){
$this->set_property('title', 'Users');
return $this;
}
function edit(){
global $adaptor, $tpl, $HTTP_SERVER_VARS;
$tpl->set_file('mwlcommunity', 'admin_mwlcommunity.tpl', 1);
$tpl->set_var('ADMIN_URL', $HTTP_SERVER_VARS['PHP_SELF']);
//showing toolbar
$tpl->process('ADD_USER', 'add_user');
//Showing users
$objects = $adaptor->retrieve_where('mwlUser', 'to_approve=0');
// uasort($objects, 'cmp_title');
if(count($objects)){
while(list($key, $obj) = each($objects)){
//user2link
$uid = $obj->get_property('_id');
// $users2links = $adaptor->retrieve_where('mwlUser2Link', "uid=$uid");
$users_loop[] = array(
'USER_ID' => $obj->get_property('_id'),
'USER_NAME' => $obj->get_property('title'),
// 'LINKS_COUNT' => count($users2links),
'USER_EMAIL' => $obj->get_property('email'),
);
}
$tpl->set_loop('users', $users_loop);
$tpl->process('SHOW_USERS', 'exist_users', 1);
}
else {
$tpl->process('SHOW_USERS', 'no_users');
}
return $tpl->process('out', 'mwlcommunity');
}
}
class mwlUser extends mwObject{
var $id;
var $hits;
function mwlUser($id = -1){
$this->mwObject($id);
$this->set_property('_class', 'mwlUser');
$this->set_property('_parent_class', 'mwlCommunity');
$this->_prop_names();
}
function delete(){
global $adaptor, $tpl, $CONF, $HTTP_POST_VARS;
$id = $this->get_property('_id');
//delete user2link
$users2links = $adaptor->retrieve_where('mwlUser2Link', "uid=$id");
while(list($key, $u2l) = each($users2links))
$u2l->delete();
// send email to user
if ( $CONF['GEN_SEND_USER_NOTIFICATIONS'] ){
$tpl->set_file('user_msg', 'email_userdelete.tpl');
$tpl->set_var( 'USER_FULLNAME', $this->get_property('title') );
if( isset( $HTTP_POST_VARS['delete_reason' . $id] ) )
$delete_reason = trim( $HTTP_POST_VARS['delete_reason' . $id] );
$delete_reason = ( strlen($delete_reason) > 0 ) ? $delete_reason : 'None';
$tpl->set_var( 'DELETE_REASON', $delete_reason );
$user_msg = $tpl->process('out', 'user_msg');
$out = process_msg( $user_msg );
send_email(
$this->get_property('email'),
'Link Department Pro',
$out['subj'],
$out['msg']
);
}
mwObject::delete();
}
function has_access($lid){
global $adaptor;
$uid = $this->get_property('_id');
$count = $adaptor->count_where('mwlUser2Link', "uid=$uid AND lid=$lid");
return $count;
}
function show_links(){
global $adaptor, $tpl;
$tpl->set_file('mwluserlinks', 'admin_userlinks.tpl', 1);
$id = $this->get_property('_id');
$users2links = $adaptor->retrieve_where('mwlUser2Link', "uid=$id");
$tpl->set_var('MWOID', $id );
$tpl->set_var('USER_NAME', $this->get_property('title') );
$tpl->set_var('USER_EMAIL', $this->get_property('email') );
$count = 0;
if( count($users2links)>0 ){
while(list($key, $u2l) = each($users2links)){
$lid = $u2l->get_property('lid');
$obj = $adaptor->get_obj($lid, 'mwlLink');
$obj->load();
if( $obj->get_property('to_approve') == 1 )
continue;
$count++;
$quest_loop[] = array(
'CHILD_QUEST_ID' => $obj->get_property('_id'),
'CHILD_QUEST_TITLE' => $obj->get_property('title'),
);
$tpl->set_loop('subquestions', $quest_loop);
$tpl->process('SHOW_QUESTS', 'exist_quests', 1);
}
}
if( ! $count )
$tpl->process('SHOW_QUESTS', 'no_quests');
return $tpl->process('out', 'mwluserlinks');
}
function edit( $buttons = array('update'), $tpl_file = 'admin_mwluser.tpl', $clickable_path = 1 ){
global $tpl;
if($buttons == 'default')
$buttons = array('update');
if($tpl_file == 'default')
$tpl_file = 'admin_mwluser.tpl';
$id = $this->get_property('_id');
$tpl->set_file('mwluser', $tpl_file, 1);
$tpl->set_var('MWOID', $id);
//new mwlUser object needs adding password field
//or with change pass action
if( $this->get_property('_id') < 0 ){
$tpl->process('PASSWORD_STUFF', 'nothing', 1);
}
else
$tpl->process('PASSWORD_STUFF', 'show_password_button', 1);
$tpl->set_var('MWOBJECT', mwObject::edit($buttons, 'default', $clickable_path));
return $tpl->process('out', 'mwluser');
}
function emailuser(){
global $tpl, $CONF;
$id = $this->get_property('_id');
$tpl->set_file('emailuser', 'admin_emailuser.tpl');
$tpl->set_var('MWOID', $id );
$tpl->set_var('USER_NAME', $this->get_property('title') );
$tpl->set_var('ADMIN_EMAIL', $CONF['GEN_ADMIN_EMAIL'] );
out( $tpl->process('out', 'emailuser') );
}
function sendemailuser(){
global $HTTP_POST_VARS;
$id = $this->get_property('_id');
$to = $this->get_property('email');
$subj = $HTTP_POST_VARS['mwl_email_subject'];
$content = $HTTP_POST_VARS['mwl_email_content'];
send_email(
$to,
'Link Department Pro',
$subj,
$content
);
out( 'An email has been sent to ' . $to );
}
function handle_action(&$post){
$id = $this->get_property('_id');
if( isset($post['action']) )
$action = $post['action'];
else
return $this;
if( $id < 0 ){ //new user, add Password field
$this->add_to_form(
array(
'pname' => 'password',
'ps' => array( 'not_shown' => 0, ),
)
);
}
if( ($action == 'changepass') || ($action == 'updatepass') ){
$this->reset_form();
$this->get_form(
array(
'pname' => 'password',
'ps' => array( 'not_shown' => 0, ),
)
);
}
switch($action){
case 'showlinks':
// $this->load();
// $this->show_links();
return $this;
break;
case 'deletelink':
$lid = $post['lid'];
$obj = new mwlLink($lid);
$obj->delete();
$post['action'] = 'showlinks';
$this->handle_action($post);
break;
case 'emailuser':
$this->emailuser();
break;
case 'sendemailuser':
$this->sendemailuser();
break;
case 'changepass':
$this->load();
out( $this->edit( array('updatepass') ) );
break;
case 'updatepass':
$this->load(); //to set all fields even not in form
if( $this->validate_input() ){
$this->store();
out('Password changed');
$this->reset_form();
$this->get_form();
out( $this->edit() );
}
else{
out( $this->edit( array('updatepass') ) );
}
break;
default:
return mwObject::handle_action($post);
}
return $this;
}
}
?>
class mwNode {
var $id;
var $title;
var $children;
function mwNode(&$array, $hidden = false, $hide_questions = false){
$this->id = $array[0];
$this->title = $array[1];
$this->is_cat = isset($array[2]) ? $array[2] : 0;
$this->children = isset($array[3]) ? $array[3] : array(); //is itself an array of arrays with node data
$this->hidden = $hidden;
$this->hide_questions = $hide_questions;
$this->shifter = " ";
}
function get_select_fill($sh = '', $skip = 0){
$array = array();
if( (! $skip ) || ($this->id != $skip) )
$array[] = array( $this->id, $sh . $this->title );
if(is_array($this->children)){
$sh .= $this->shifter;
while(list($id, $child_data) = each($this->children)){
$child = new mwNode($child_data);
$to_add = $child->get_select_fill( $sh, $skip);
foreach( $to_add as $v)
$array[] = $v;
}
}
return $array;
}
function print_select_cat($sel = 0, $sh = ''){
$selected = ( $sel == $this->id) ? ' SELECTED' : '';
$string = "