[phpBB Debug] PHP Warning: in file [ROOT]/ext/tas2580/seourls/event/listener.php on line 213: Undefined array key "FORUM_NAME"
Redaxo Modul-Versionierung BETA 0.1 - REDAXO Forum
Hallo,

Wir haben in letzter Zeit festgestellt, dass die Kommunikation via Slack viel schneller und zielführender ist als ein Beitrag im Forum. Aufgrund der neuen und besseren Möglichkeiten der Kommunikation haben wir uns entschlossen das Forum nur noch als Archiv zur Verfügung zu stellen. Somit bleibt es weiterhin möglich hier nach Lösungen zu suchen. Neue Beiträge können nicht mehr erstellt werden.

Wir empfehlen, für deine Fragen/Probleme Slack zu nutzen. Dort sind viele kompetente Benutzer aktiv und beantworten jegliche Fragen, gerne auch von REDAXO-Anfängern! Slack wird von uns sehr intensiv und meistens "rund um die Uhr" benutzt :-)
Selbst einladen kannst Du dich hier: https://redaxo.org/slack/
Hirbod
Beiträge: 435
Registriert: 15. Jan 2008, 14:46

Redaxo Modul-Versionierung BETA 0.1

24. Feb 2010, 11:50

Hallo liebe Gemeine,

das Addon Arbeitsversion gefällt mir nicht... Redaxo hat keine anständige Versionierung. Erst vorgestern ist Arbeit von 6 Stunden einfach verloren gegangen, weil ich versehentlich ein Modul überschrieben habe - und natürlich kein Backup habe.

Das ist jetzt erstmal als "Quick and Dirty" Version anzusehen, wird in Zukunft dann über ein Addon gelöst. Sobald ein Modul angelegt, gespeichert oder geupdated wird, wird eine Kopie davon in der Datenbank gespeichert. Aktuell noch keine grafische Ausgabe, jedoch existieren die Felder in der Datenbank - im worst case kann man dann per PHPmyAdmin das Modul retten. Wird demnächst komplett auf Redaxo erweitert, sodass wirklich alles Versioniert wird. Aktuell werden 50 Versionen gespeichert, danach wird überschrieben.

Sehr hilfreich.

ACHTUNG, BACKUPS ANLEGEN. DAS IST HIGHLY BETA, ICH GARANTIERE FÜR NICHTS. DAS IST EIN TIEFER EINGRIFF IN DEN CORE. UNBEDINGT BACKUPS MACHEN, TESTEN, MIR BESCHEID GEBEN


Step 1:
phpMyAdmin öffnen, Datenbank wählen, auf SQL klicken:

Code: Alles auswählen

CREATE TABLE `sl_versions` (
  `version` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `ausgabe` text,
  `eingabe` text,
  `createuser` varchar(255) DEFAULT NULL,
  `updateuser` varchar(255) DEFAULT NULL,
  `revision` int(11) DEFAULT NULL,
  `modul` int(11) NOT NULL,
  PRIMARY KEY (`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Step 2:
Komplette module.modules.inc.php ersetzen durch:

Code: Alles auswählen

<?php
/**
 *
 * @package redaxo4
 * @version svn:$Id$
 */

$OUT = TRUE;

$function        = rex_request('function', 'string');
$function_action = rex_request('function_action', 'string');
$save            = rex_request('save','string');
$modul_id        = rex_request('modul_id', 'rex-module-id');
$action_id       = rex_request('action_id', 'rex-action-id');
$iaction_id      = rex_request('iaction_id','int'); // id der module-action relation
$mname           = rex_request('mname','string');
$eingabe         = rex_request('eingabe','string');
$ausgabe         = rex_request('ausgabe','string');
$goon            = rex_request('goon','string');
$add_action      = rex_request('add_action','string');

$info = '';
$warning = '';
$warning_block = '';

// ---------------------------- ACTIONSFUNKTIONEN FÜR MODULE
if ($add_action != "")
{
  $action = new rex_sql();
  $action->setTable($REX['TABLE_PREFIX'].'module_action');
  $action->setValue('module_id', $modul_id);
  $action->setValue('action_id', $action_id);

  if($action->insert())
  {
    $info = $I18N->msg('action_taken');
    $goon = '1';
  }
  else
  {
    $warning = $action->getErrro();
  }
}
elseif ($function_action == 'delete')
{
  $action = new rex_sql();
  $action->setTable($REX['TABLE_PREFIX'].'module_action');
  $action->setWhere('id='. $iaction_id . ' LIMIT 1');

  $info = $action->delete($I18N->msg('action_deleted_from_modul'));
}



// ---------------------------- FUNKTIONEN FÜR MODULE

if ($function == 'delete')
{
  $del = new rex_sql;
  $del->setQuery("SELECT ".$REX['TABLE_PREFIX']."article_slice.article_id, ".$REX['TABLE_PREFIX']."article_slice.clang, ".$REX['TABLE_PREFIX']."article_slice.ctype, ".$REX['TABLE_PREFIX']."module.name FROM ".$REX['TABLE_PREFIX']."article_slice
      LEFT JOIN ".$REX['TABLE_PREFIX']."module ON ".$REX['TABLE_PREFIX']."article_slice.modultyp_id=".$REX['TABLE_PREFIX']."module.id
      WHERE ".$REX['TABLE_PREFIX']."article_slice.modultyp_id='$modul_id' GROUP BY ".$REX['TABLE_PREFIX']."article_slice.article_id");

  if ($del->getRows() >0)
  {
    $module_in_use_message = '';
    $modulname = htmlspecialchars($del->getValue($REX['TABLE_PREFIX']."module.name"));
    for ($i=0; $i<$del->getRows(); $i++)
    {
      $aid = $del->getValue($REX['TABLE_PREFIX']."article_slice.article_id");
      $clang_id = $del->getValue($REX['TABLE_PREFIX']."article_slice.clang");
      $ctype = $del->getValue($REX['TABLE_PREFIX']."article_slice.ctype");
      $OOArt = OOArticle::getArticleById($aid, $clang_id);

      $label = $OOArt->getName() .' ['. $aid .']';
      if(count($REX['CLANG']) > 1)
        $label = '('. rex_translate($REX['CLANG'][$clang_id]) .') '. $label;

      $module_in_use_message .= '<li><a href="index.php?page=content&article_id='. $aid .'&clang='. $clang_id .'&ctype='. $ctype .'">'. htmlspecialchars($label) .'</a></li>';
      $del->next();
    }

    if($module_in_use_message != '')
    {
      $warning_block = '<ul>' . $module_in_use_message . '</ul>';
    }

    $warning = $I18N->msg("module_cannot_be_deleted",$modulname);
  } else
  {
    $del->setQuery("DELETE FROM ".$REX['TABLE_PREFIX']."module WHERE id='$modul_id'");
    $del->setQuery("DELETE FROM ".$REX['TABLE_PREFIX']."module_action WHERE module_id='$modul_id'");

    $info = $I18N->msg("module_deleted");
  }
}

if ($function == 'add' or $function == 'edit')
{
  if ($save == '1')
  {
    $modultyp = new rex_sql;

    if ($function == 'add')
    {
      // $modultyp->setQuery("INSERT INTO ".$REX['TABLE_PREFIX']."modultyp (category_id, name, eingabe, ausgabe) VALUES ('$category_id', '$mname', '$eingabe', '$ausgabe')");

      $IMOD = new rex_sql;
      $IMOD->setTable($REX['TABLE_PREFIX'].'module');
      $IMOD->setValue('name',$mname);
      $IMOD->setValue('eingabe',$eingabe);
      $IMOD->setValue('ausgabe',$ausgabe);
      $IMOD->addGlobalCreateFields();

      if($IMOD->insert())
        $info = $I18N->msg('module_added');
      else
        $warning = $IMOD->getError();

    } else {
      $modultyp->setQuery('select * from '.$REX['TABLE_PREFIX'].'module where id='.$modul_id);
      if ($modultyp->getRows()==1)
      {
        $old_ausgabe = $modultyp->getValue('ausgabe');

        // $modultyp->setQuery("UPDATE ".$REX['TABLE_PREFIX']."modultyp SET name='$mname', eingabe='$eingabe', ausgabe='$ausgabe' WHERE id='$modul_id'");

        $UMOD = new rex_sql;
        $UMOD->setTable($REX['TABLE_PREFIX'].'module');
        $UMOD->setWhere('id='. $modul_id);
        $UMOD->setValue('name',$mname);
        $UMOD->setValue('eingabe',$eingabe);
        $UMOD->setValue('ausgabe',$ausgabe);
        $UMOD->addGlobalUpdateFields();

        if($UMOD->update())
          $info = $I18N->msg('module_updated').' | '.$I18N->msg('articel_updated');
        else
          $warning = $UMOD->getError();

        $new_ausgabe = stripslashes($ausgabe);

		if ($old_ausgabe != $new_ausgabe)
		{
          // article updaten - nur wenn ausgabe sich veraendert hat
          $gc = new rex_sql;
          $gc->setQuery("SELECT DISTINCT(".$REX['TABLE_PREFIX']."article.id) FROM ".$REX['TABLE_PREFIX']."article
              LEFT JOIN ".$REX['TABLE_PREFIX']."article_slice ON ".$REX['TABLE_PREFIX']."article.id=".$REX['TABLE_PREFIX']."article_slice.article_id
              WHERE ".$REX['TABLE_PREFIX']."article_slice.modultyp_id='$modul_id'");
          for ($i=0; $i<$gc->getRows(); $i++)
          {
          	rex_deleteCacheArticle($gc->getValue($REX['TABLE_PREFIX']."article.id"));
            $gc->next();
          }
        }
      }
    }

    if ($goon != '')
    {
      $save = '0';
    } else
    {
      $function = '';
    }
  $nModulSL = $_POST['modul_id'];
	$nCategorySL = $_POST['category_id'];
	// geänderte Version aus Datenbank auslesen und in versionierungstabelle speichern
	
	// Anzahl an Revisionen, die in der Datenbank gespeichert werden
	$nKeep = 5;
	
	$hSqlSL = new rex_sql();
	
	$sQuerySL = '	SELECT	ausgabe, eingabe, createuser, updateuser, revision
								FROM		' . $REX['TABLE_PREFIX'] . 'module
								WHERE		id = ' . $nModulSL . '
									AND		category_id = ' . $nCategorySL . '
								LIMIT 0, 1';
	$hSqlSL->setQuery($sQuerySL);
	
	$sAusgabeSL = $hSqlSL->getValue('ausgabe');
	$sEingabeSL = $hSqlSL->getValue('eingabe');
	$sCreateUserSL = $hSqlSL->getValue('createuser');
	$sUpdateUserSL = $hSqlSL->getValue('updateuser');
	$sRevisionSL = $hSqlSL->getValue('revision');
	
	$hSqlSL->flush();
	
	$sInsertSL = '	INSERT INTO sl_versions (ausgabe, eingabe, createuser, updateuser, revision, modul)
									VALUES (
										"' . $sAusgabeSL . '",
										"' . $sEingabeSL . '",
										"' . $sCreateUserSL . '",
										"' . $sUpdateUserSL . '",
										' . $sRevisionSL . ',
										' . $nModulSL . '
									)';
	$hSqlSL->setQuery($sInsertSL);
	$hSqlSL->flush();
	
	$sCheck = '	SELECT	COUNT(*) as anzahl
							FROM		sl_versions
							WHERE		modul = ' . $nModulSL;
	$hSqlSL->setQuery($sCheck);
	$nAnzahlSL = $hSqlSL->getValue('anzahl');
	$hSqlSL->flush();
	
	if($nAnzahlSL > $nKeep) {
		$sDeleteSL = '	SELECT		version
										FROM			sl_versions
										ORDER BY	version ASC';
		$hSqlSL->setQuery($sDeleteSL);

		$saDeleteSL = array();
		for($nAktu = 0; $nAktu < $hSqlSL->getRows(); $nAktu++) {

			$saDeleteSL[] = $hSqlSL->getValue('version');

			if($nAktu >= $nAnzahlSL - $nKeep - 1) {
				break;
			}
			else {
				$hSqlSL->next();
			}
		}

		$sIn = null;
		foreach($saDeleteSL as $sDeleteIdSL) {
			if($sIn != null) {
				$sIn .= ',';
			}
			$sIn .= '"' . $sDeleteIdSL . '"';
		}
		$sDeleteSL = '	DELETE FROM sl_versions WHERE version IN (' . $sIn . ')';
		$hSqlSL->setQuery($sDeleteSL);
		$hSqlSL->flush();
	}

	$hSqlSL->disconnect();
	
	}



  if ($save != '1')
  {
    if ($function == 'edit')
    {
      $legend = $I18N->msg('module_edit').' [ID='.$modul_id.']';

      $hole = new rex_sql;
      $hole->setQuery('SELECT * FROM '.$REX['TABLE_PREFIX'].'module WHERE id='.$modul_id);
      $category_id  = $hole->getValue('category_id');
      $mname    = $hole->getValue('name');
      $ausgabe  = $hole->getValue('ausgabe');
      $eingabe  = $hole->getValue('eingabe');
    }
    else
    {
      $legend = $I18N->msg('create_module');
    }

    $btn_update = '';
    if ($function != 'add') $btn_update = '<input type="submit" class="rex-form-submit rex-form-submit-2" name="goon" value="'.$I18N->msg("save_module_and_continue").'"'. rex_accesskey($I18N->msg('save_module_and_continue'), $REX['ACKEY']['APPLY']) .' />';

    if ($info != '')
      echo rex_info($info);

    if ($warning != '')
      echo rex_warning($warning);

    if ($warning_block != '')
      echo rex_warning_block($warning_block);

    echo '
			<div class="rex-form rex-form-module-editmode">
      	<form action="index.php" method="post">
        <fieldset class="rex-form-col-1">
          <legend>'. $legend .'</legend>
      	  <div class="rex-form-wrapper">
						<input type="hidden" name="page" value="module" />
						<input type="hidden" name="function" value="'.$function.'" />
						<input type="hidden" name="save" value="1" />
						<input type="hidden" name="category_id" value="0" />
						<input type="hidden" name="modul_id" value="'.$modul_id.'" />
						
						<div class="rex-form-row">
    			  	<p class="rex-form-col-a rex-form-text">
      					<label for="mname">'.$I18N->msg("module_name").'</label>
	      				<input class="rex-form-text" type="text" size="10" id="mname" name="mname" value="'.htmlspecialchars($mname).'" />
  	  			  </p>
    				</div>
						<div class="rex-form-row">
    				  <p class="rex-form-col-a rex-form-textarea">
      					<label for="eingabe">'.$I18N->msg("input").'</label>
      					<textarea class="rex-form-textarea" cols="50" rows="6" name="eingabe" id="eingabe">'.htmlspecialchars($eingabe).'</textarea>
    				  </p>
    				</div>
						<div class="rex-form-row">
    			  	<p class="rex-form-col-a rex-form-textarea">
      					<label for="ausgabe">'.$I18N->msg("output").'</label>
	      				<textarea class="rex-form-textarea" cols="50" rows="6" name="ausgabe" id="ausgabe">'.htmlspecialchars($ausgabe).'</textarea>
  	  			  </p>
    				</div>
              
            <div class="rex-clearer"></div>
    			</div>
        </fieldset>
        
				<fieldset class="rex-form-col-1">
      		<div class="rex-form-wrapper">
						<div class="rex-form-row">
    				  <p class="rex-form-col-a rex-form-submit">
      					<input class="rex-form-submit" type="submit" value="'.$I18N->msg("save_module_and_quit").'"'. rex_accesskey($I18N->msg('save_module_and_quit'), $REX['ACKEY']['SAVE']) .' />
        				'. $btn_update .'
      				</p>
    				</div>
    		  </div>
        </fieldset>
    ';

    if ($function == 'edit')
    {
      // Im Edit Mode Aktionen bearbeiten

      $gaa = new rex_sql;
      $gaa->setQuery("SELECT * FROM ".$REX['TABLE_PREFIX']."action ORDER BY name");

      if ($gaa->getRows()>0)
      {
        $gma = new rex_sql;
        $gma->setQuery("SELECT * FROM ".$REX['TABLE_PREFIX']."module_action, ".$REX['TABLE_PREFIX']."action WHERE ".$REX['TABLE_PREFIX']."module_action.action_id=".$REX['TABLE_PREFIX']."action.id and ".$REX['TABLE_PREFIX']."module_action.module_id='$modul_id'");
				
				$add_header = '';
				$add_col = '';
				if ($REX['USER']->hasPerm('advancedMode[]'))
				{
					$add_header = '<th class="rex-small">'.$I18N->msg('header_id').'</th>';
					$add_col = '<col width="40" />';
				}
				
        $actions = '';
        for ($i=0; $i<$gma->getRows(); $i++)
        {
          $iaction_id = $gma->getValue($REX['TABLE_PREFIX'].'module_action.id');
          $action_id = $gma->getValue($REX['TABLE_PREFIX'].'module_action.action_id');
          $action_edit_url = 'index.php?page=module&subpage=actions&action_id='.$action_id.'&function=edit';
          $action_name = rex_translate($gma->getValue('name'));

          $actions .= '<tr>
          	<td class="rex-icon"><a class="rex-i-element rex-i-action" href="'. $action_edit_url .'"><span class="rex-i-element-text">' . htmlspecialchars($action_name) . '</span></a></td>';
          	
					if ($REX['USER']->hasPerm('advancedMode[]'))
					{
             $actions .= '<td class="rex-small">' . $gma->getValue("id") . '</td>';
          }
          	
          $actions .= '<td><a href="'. $action_edit_url .'">'. $action_name .'</a></td>
          	<td><a href="index.php?page=module&modul_id='.$modul_id.'&function_action=delete&function=edit&iaction_id='.$iaction_id.'" onclick="return confirm(\''.$I18N->msg('delete').' ?\')">'.$I18N->msg('action_delete').'</a></td>
          </tr>';

          $gma->next();
        }

        if($actions !='')
        {
          $actions = '
  					<table class="rex-table" summary="'.$I18N->msg('actions_added_summary').'">
  						<caption>'.$I18N->msg('actions_added_caption').'</caption>
    					<colgroup>
      				<col width="40" />
      				'.$add_col.'
      				<col width="*" />
      				<col width="153" />
    					</colgroup>
    					<thead>
      					<tr>
        					<th class="rex-icon">&nbsp;</th>
        					'.$add_header.'
        					<th>' . $I18N->msg('action_name') . '</th>
        					<th>' . $I18N->msg('action_functions') . '</th>
      					</tr>
    					</thead>
    				<tbody>
              '. $actions .'
            </tbody>
            </table>
          ';
        }

        $gaa_sel = new rex_select();
        $gaa_sel->setName('action_id');
        $gaa_sel->setId('action_id');
        $gaa_sel->setSize(1);
        $gaa_sel->setStyle('class="rex-form-select"');

        for ($i=0; $i<$gaa->getRows(); $i++)
        {
          $gaa_sel->addOption(rex_translate($gaa->getValue('name'), null, false),$gaa->getValue('id'));
          $gaa->next();
        }

        echo
        $actions .'
				<fieldset class="rex-form-col-1">
          <legend>'.$I18N->msg('action_add').'</legend>
      		<div class="rex-form-wrapper">
						
						<div class="rex-form-row">
							<p class="rex-form-col-a rex-form-select">
								<label for="action_id">'.$I18N->msg('action').'</label>
								'.$gaa_sel->get().'
					  	</p>
					  </div>
					  
						<div class="rex-form-row">
					  	<p class="rex-form-col-a rex-form-submit">
								<input class="rex-form-submit" type="submit" value="'.$I18N->msg('action_add').'" name="add_action" />
					  	</p>
					  </div>
				  </div>
        </fieldset>';
      }
    }

    echo '
    </form></div>
    ';

    $OUT = false;
  }
	
}

if ($OUT)
{
  if ($info != '')
    echo rex_info($info);

  if ($warning != '')
    echo rex_warning($warning);

  if ($warning_block != '')
    echo rex_warning_block($warning_block);

  $list = rex_list::factory('SELECT id, name FROM '.$REX['TABLE_PREFIX'].'module ORDER BY name');
  $list->setCaption($I18N->msg('module_caption'));
  $list->addTableAttribute('summary', $I18N->msg('module_summary'));
  $list->addTableColumnGroup(array(40, 40, '*', 153));

  $tdIcon = '<span class="rex-i-element rex-i-module"><span class="rex-i-element-text">###name###</span></span>';
  $thIcon = '<a class="rex-i-element rex-i-module-add" href="'. $list->getUrl(array('function' => 'add')) .'"'. rex_accesskey($I18N->msg('create_module'), $REX['ACKEY']['ADD']) .'><span class="rex-i-element-text">'.$I18N->msg('create_module').'</span></a>';
  $list->addColumn($thIcon, $tdIcon, 0, array('<th class="rex-icon">###VALUE###</th>','<td class="rex-icon">###VALUE###</td>'));
  $list->setColumnParams($thIcon, array('function' => 'edit', 'modul_id' => '###id###'));

  $list->setColumnLabel('id', 'ID');
  $list->setColumnLayout('id', array('<th class="rex-small">###VALUE###</th>','<td class="rex-small">###VALUE###</td>'));

  $list->setColumnLabel('name', $I18N->msg('module_description'));
  $list->setColumnParams('name', array('function' => 'edit', 'modul_id' => '###id###'));

  $list->addColumn($I18N->msg('module_functions'), $I18N->msg('delete_module'));
  $list->setColumnParams($I18N->msg('module_functions'), array('function' => 'delete', 'modul_id' => '###id###'));
  $list->addLinkAttribute($I18N->msg('module_functions'), 'onclick', 'return confirm(\''.$I18N->msg('delete').' ?\')');

	$list->setNoRowsMessage($I18N->msg('modules_not_found'));

  $list->show();
}
Bitte testen und mir Feedback geben. GUI, automatischer Restore über ein Addon etc wird demnächst realisiert.

Lg
Hbod

jones
Beiträge: 16
Registriert: 15. Mai 2009, 20:00

24. Feb 2010, 19:16

Tolle Sache!

Ich werds mal testen.

Vielen Dank, Jonas

Zurück zu „Allgemeines [R4]“