[interchange-cvs] interchange - heins modified 4 files

interchange-cvs at icdevgroup.org interchange-cvs at icdevgroup.org
Sun Jul 27 01:30:00 EDT 2003


User:      heins
Date:      2003-07-27 04:30:54 GMT
Modified:  code/UI_Tag if_mm.coretag
Modified:  dist/foundation catalog.cfg
Modified:  dist/foundation/products variable.txt
Modified:  dist/lib/UI ui.cfg
Log:
* Add ability to edit pages using Mozilla composer, or any HTML editor
  that can publish with an HTTP put. Includes ability to upload images
  with the files, create new files, and more.

* ONLY operates on the area between <!-- BEGIN CONTENT --> and
  <!-- END CONTENT -->.

* Pulls the page title from the <title></title> of the PUT page.

* If a new page is PUT, it is wrapped with the template used in
  the nearest DirectoryIndex ("index" by default). If a new file
  "trucks/chevy/mom.html" is created and does not exist, the following
  files will be used as the template in this order if they exist:

    trucks/chevy/index
    trucks/index
    index

* Update [if-mm ...] to have a "pagematch" and "filematch" function
  that allows security checks based on the files and pages fields
  in the access table. This allows certain users to have publish
  permission only on certain image and page directories. For
  instance, if the user "bubba" is only to edit files in the
  "trucks" hierarchy, you would want in access:

    username:bubba
    files:images/trucks/
    pages:trucks/

* Add action "admin_publish" that handles the PUT process. Requires
  user be logged in as an admin, and requires

* Automatic RCS versioning if PUBLISH_DO_RCS variable is set. Can
  stop publish if RCS error when PUBLISH_QUIT_ON_RCS_ERROR Variable
  is set.

* Adding "ui_mozilla_edit=1" to the URL keeps ITL tags from being
  interpolated within the BEGIN CONTENT/END CONTENT area. This
  allows

* Automatically adjusts image paths in the uploaded file to be
  relative to the directory the page is in. This allows individual
  directories to use different sets of images and Mozilla won't
  willy-nilly overwrite things in other directories.

* Handles most <a href="[area ...]"> things, I think. This can
  probably be improved.

* Can prevent any publishing to the pages root if PUBLISH_NO_PAGE_ROOT
  is set.

* TODO: Handle delivery and upload of Flash and other types of
  things besides images.

* TODO: Add <meta ...> tag handling to allow component adjustments.

Revision  Changes    Path
1.3       +31 -0     interchange/code/UI_Tag/if_mm.coretag


rev 1.3, prev_rev 1.2
Index: if_mm.coretag
===================================================================
RCS file: /var/cvs/interchange/code/UI_Tag/if_mm.coretag,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- if_mm.coretag	7 Feb 2002 02:43:46 -0000	1.2
+++ if_mm.coretag	27 Jul 2003 04:30:54 -0000	1.3
@@ -71,6 +71,10 @@
 						tables  tables
 						table   tables
 					/;
+	my %prefix_func = qw/
+						filematch  files
+						pagematch  pages
+					/;
 
 	my $table = $CGI::values{mv_data_table} || $::Values->{mv_data_table};
 	
@@ -92,12 +96,39 @@
 		my $file = $field || $Global::Variable->{MV_PAGE};
 		# strip trailing slashes for checks on directories
 		$file =~ s%/+$%%;                     
+#::logDebug("check=$check file=$file record=$record->{$check} prefix=$opt->{prefix}");
 		my @files =  UI::Primitive::list_glob($record->{$check}, $opt->{prefix});
+#::logDebug("check yielded files=" . join(",", @files));
 		if(! @files) {
 			$status = '';
 			last CHECKIT;
 		}
 		$status = ui_check_acl("$file$extended", join(" ", @files));
+#::logDebug("check status=$status");
+		last CHECKIT;
+	}
+	if($check = $prefix_func{$func}) {
+		$status = '', last CHECKIT unless $record->{$check};
+		my $file = $field;
+		# strip trailing slashes for checks on directories
+#::logDebug("check=$check file=$file record=$record->{$check}");
+		my @allow =  split /\s+/, $record->{$check};
+		$status = '';
+		for(@allow) {
+#::logDebug("check file=$file against allow=$_");
+			if(s/^\!//) {
+				if ($file =~ /^$_/) {
+#::logDebug("denied based on $_");
+					$status = '';
+					last CHECKIT;
+				}
+			}
+			else {
+				next unless $file =~ /^$_\b/;
+				$status = 1; 
+			}
+		}
+#::logDebug("check Yielded status=$status");
 		last CHECKIT;
 	}
 	if($bool_func{$func} ) {



2.24      +3 -0      interchange/dist/foundation/catalog.cfg


rev 2.24, prev_rev 2.23
Index: catalog.cfg
===================================================================
RCS file: /var/cvs/interchange/dist/foundation/catalog.cfg,v
retrieving revision 2.23
retrieving revision 2.24
diff -u -r2.23 -r2.24
--- catalog.cfg	21 Jul 2003 17:53:37 -0000	2.23
+++ catalog.cfg	27 Jul 2003 04:30:54 -0000	2.24
@@ -111,6 +111,9 @@
 ImageDir          __IMAGE_DIR__/
 ImageDirInternal  http://__SERVER_NAME____IMAGE_DIR__/
 
+## This is put in so Mozilla's brain-dead composer refetch function won't fail
+DeliverImage  yes
+
 #==========================================================================#
 
 # Here we set up the catalog theme.



2.32      +5 -0      interchange/dist/foundation/products/variable.txt


rev 2.32, prev_rev 2.31
Index: variable.txt
===================================================================
RCS file: /var/cvs/interchange/dist/foundation/products/variable.txt,v
retrieving revision 2.31
retrieving revision 2.32
diff -u -r2.31 -r2.32
--- variable.txt	25 Jun 2003 15:32:55 -0000	2.31
+++ variable.txt	27 Jul 2003 04:30:54 -0000	2.32
@@ -51,6 +51,11 @@
 PHONE	__MVC_PHONE__	Company
 POSTAL_ACCEPTED	0	Payment
 PO_ACCEPTED	__MVC_PAYPO__	Payment
+PUBLISH_DO_RCS	0	Admin Control
+PUBLISH_NO_PAGE_ROOT	0	Admin Control
+PUBLISH_PUT_IMAGES	images	Admin Control
+PUBLISH_PUT_PAGES	pages	Admin Control
+PUBLISH_QUIT_ON_RCS_ERROR	0	Admin Control
 SAMPLEHTML	__MVC_SAMPLEHTML__	Directories and Paths
 SAMPLEURL	__MVC_SAMPLEURL__	Directories and Paths
 SECURE_ENABLE	__MVC_ENABLESECURE__	General



2.11      +268 -0    interchange/dist/lib/UI/ui.cfg


rev 2.11, prev_rev 2.10
Index: ui.cfg
===================================================================
RCS file: /var/cvs/interchange/dist/lib/UI/ui.cfg,v
retrieving revision 2.10
retrieving revision 2.11
diff -u -r2.10 -r2.11
--- ui.cfg	27 Jan 2003 19:03:36 -0000	2.10
+++ ui.cfg	27 Jul 2003 04:30:54 -0000	2.11
@@ -49,13 +49,18 @@
 	return unless $Vend::admin;
 	my $tmpd = $Vend::Cfg->{ScratchDir};
 	$tmpd .= "/previews/$Vend::SessionID";
+#::logDebug("tmpd = $tmpd");
 	$Vend::Cfg->{PreviewDir} = $tmpd if -d $tmpd;
+#::logDebug("PreviewDir=$Vend::Cfg->{PreviewDir}");
 	$::Variable->{ADL_SUFFIX} = $Vend::Cfg->{HTMLsuffix};
 	$::Variable->{ADL_PAGE} = $::Variable->{ADL_PAGE_TEMPLATE} || <<EOF;
 [page href="admin/content_editor" form="
 			ui_name=[var MV_PAGE 1][var ADL_SUFFIX]
 			ui_type=page
 		"][loc]edit[/loc]&nbsp;[loc]page[/loc]</A>
+[page href="[var MV_PAGE 1]" form="
+			ui_mozilla_edit=1
+		"][loc]show&nbsp;tags[/loc]</A>
 EOF
 
 	$::Variable->{ADL_COMPONENT} = $::Variable->{ADL_COMPONENT_TEMPLATE} || <<EOF;
@@ -65,6 +70,15 @@
 		"][loc]edit[/loc]&nbsp;[control component]</A>
 EOF
 
+	$::Variable->{ADL_ITEM} = $::Variable->{ADL_ITEM_TEMPLATE} || <<EOF;
+<a href="[area
+			href=admin/item_edit
+			form=|
+				item_id=[item-code]
+				ui_return_to=index
+			|
+		]">[loc]edit[/loc]&nbsp;[loc]item[/loc]</A>
+EOF
 	$::Variable->{ADL_MENU} = $::Variable->{ADL_MENU_TEMPLATE} || <<EOF;
 <a class="[control link_class]"
 	href="[area
@@ -74,10 +88,264 @@
 			|
 		]">[loc]edit[/loc]&nbsp;[loc]menu[/loc]</A>
 EOF
+
+	if($CGI::values{ui_mozilla_edit}) {
+		$::Pragma->{init_page} = 'show_tags_for_edit';
+	}
 	return;
 
 }
 EOS
+
+GlobalSub <<EOS
+sub show_tags_for_edit {
+	my $html = shift;
+	$$html =~ s{(<!--+\s*BEGIN\s+CONTENT\s*--+>)}{[strip reparse=0]$1};
+	$$html =~ s{(<!--+\s*END\s+CONTENT\s*--+>)}{$1\[/strip]};
+}
+EOS
+
+ActionMap admin_publish <<EOR
+sub {
+	require HTML::HeadParser;
+	my $path = shift;
+#::logDebug("Path is $path");
+
+	use vars qw/
+		$Tag
+	/;
+	
+#::logDebug("env is " . ::uneval(Vend::Dispatch::http()->{env}));
+
+	$Vend::Extension and $path .= $Vend::Cfg->{HTMLsuffix};
+
+	unless($CGI::request_method eq 'PUT') {
+		$Tag->deliver('text/html', { status => "405 Not Implemented" }, 0);
+		logError("admin_publish expecting PUT.");
+		return;
+	}
+
+	unless($Vend::admin) {
+		$Tag->deliver('text/html', { status => "403 forbidden" }, 0);
+		logError("PUT by non-admin, quitting.");
+		return;	
+	}
+
+	my $mimetype = Vend::Util::mime_type($path);
+
+	my $publish_dir;
+	my $icpage;
+	my $umask;
+	my $orig_umask;
+
+	if($mimetype eq 'text/html') {
+		$icpage = 1;
+		$publish_dir = $::Variable->{PUBLISH_PUT_PAGES}  || 'pages';
+		unless($Tag->if_mm('pagematch', $path)) {
+			$Tag->deliver('text/html', { status => "403 forbidden" }, 0);
+			logError("User %s not authorized for page %s.", $Vend::username, $path);
+			return;	
+		}
+	}
+	else {
+		$publish_dir = $::Variable->{PUBLISH_PUT_IMAGES} || 'images';
+		unless($Tag->if_mm('filematch', "$publish_dir/$path")) {
+			$Tag->deliver('text/html', { status => "403 forbidden" }, 0);
+			logError(
+					"User %s not authorized for file %s.",
+					$Vend::username,
+					"$publish_dir/$path",
+				);
+			return;	
+		}
+		$umask = oct($::Variable->{PUBLISH_IMAGES_UMASK} || 2);
+	}
+
+	if(	$::Variable->{PUBLISH_NO_PAGE_ROOT}
+		and $mimetype eq 'text/html'
+		and $path !~ m{/}
+	) {
+		$Tag->deliver('text/html', { status => "403 forbidden" }, 0);
+		logError("PUT in top level of page directory not allowed.");
+		return;	
+	}
+
+	my %header;
+
+	CREATEPAGE: {
+		my $top;
+		my $bottom;
+
+		last CREATEPAGE unless $icpage;
+
+		$::Pragma->{no_locale_parse} = 1;
+		my $origfile = readin($path);
+
+		my $dir = $path;
+		$dir =~ s:/[^/]+$::
+			or $dir = '';
+
+		GETPAGE: {
+			last GETPAGE if $origfile;
+			my $newpath = $path;
+			my $idx = $Vend::Cfg->{DirectoryIndex} || 'index';
+			while(! $origfile and $newpath =~ s:/?([^/]+)$::) {
+				$origfile = readin(Vend::File::catfile($newpath, $idx));
+			}
+		}
+		if(! $origfile) {
+			::logDebug("Cannot find template file, publishing as is.");
+			last CREATEPAGE;
+		}
+		$origfile =~ s{(.*)\s*<!--+\s+BEGIN\s+CONTENT\s+--+>}{}s
+			and $top = $1;
+		$origfile =~ s{.*<!--+\s+END\s+CONTENT\s+--+>\s*}{}s
+			and $bottom = $origfile;
+		my $content = $$CGI::put_ref;
+
+		my $p = HTML::HeadParser->new();
+
+		$p->parse($content);
+		$header{page_title} = $p->header('title');
+#::logDebug("header title=$header{page_title} object" . ::uneval($p));
+		$top =~ s{(\[(seti?|tmpn?)\s+(\w+)\s*\])(.*?)(\[/\2\])}
+				{$1 . ($header{$3} || $4) . $5}eg;
+
+		$content =~ s{.*<!--+\s+BEGIN\s+CONTENT\s+--+>\s*}{}s
+			or $content =~ s:.*<body.*?>\s*::is;
+		$content =~ s{\s*<!--+\s+END\s+CONTENT\s+--+>.*}{}s
+			or $content =~ s:\s*</body\s*>.*::is;
+		$content =~ s/\r\n/\n/g;
+
+		my %strip_vars;
+		my $strip_init;
+
+		my $change_sub = sub {
+			my $url = shift;
+			return $url if $url =~ m{^\w+:};
+			return $url if $url =~ m{^[[/]};
+			my @parts = split m{/}, $dir;
+			while($url =~ s{^../}{}) {
+				splice @parts, -1, 1;
+			}
+			my $newdir = join "/", @parts;
+			$url = "$newdir/$url" if $newdir;
+
+			my $arg;
+			my @args;
+			my @out;
+			($url, $arg) = split /[?&]/, $url, 2;
+			@args = split $Global::UrlSplittor, $arg;
+			if(@args) {
+				for(@args) {
+					my ($var, $val) = split /=/, $_, 2;
+					next if $strip_vars{$var};
+					push @out, "$var=" . unhexify($_);
+				}
+				my $fstr = join "\n", @out;
+				return qq{[area href='$url' form=|$fstr|]};
+			}
+			return qq{[area $url]};
+		};
+
+		1 while $content =~ s{(<\w+[^>]*\s+[-\w]+\s*=\s*")([^"]*\%5b.*?\%5d)}
+							{$1 . unhexify($2)}ie;
+		if($dir) {
+			$dir =~ s:/*$:/:;
+			$content =~ s{(<a\s+[^>]*href\s*=\s*)(["'])(\.\.[^'"]+)\2}
+							{$1 . $2 . $change_sub->($3) . $2}gei;
+			$content =~ s#(<i\w+\s+[^>]*?src=")(?!\w+:)([^/'][^"]+)#
+						$1 . $dir . $2#ige;
+			$content =~ s#(<body\s+[^>]*?background=")(?!\w+:)([^/'][^"]+)#
+						$1 . $dir . $2#ige;
+			$content =~ s#(<t(?:[dhr]|able)\s+[^>]*?background=")(?!\w+:)([^/'][^"]+)#
+							$1 . $dir . $2#ige;
+		}
+
+		$$CGI::put_ref = join "\n",
+							$top,
+							'<!-- BEGIN CONTENT -->',
+							$content,
+							'<!-- END CONTENT -->',
+							$bottom;
+	}
+
+	if($::Variable->{PUBLISH_TO_PREVIEWS}) {
+		$Vend::Cfg->{PreviewDir} ||=
+			catfile($Vend::Cfg->{ScratchDir}, 'previews', $Vend::SessionID);
+		$publish_dir = $Vend::Cfg->{PreviewDir};
+		$publish_dir =~ s{^$Vend::Cfg->{VendRoot}/*}{};
+	}
+
+#::logDebug("PUBLISH_DIR=$publish_dir FILE=$path");
+
+	my $fn = catfile($publish_dir, $path);
+
+	$orig_umask = umask($umask) if $umask;
+
+	if($icpage and $::Variable->{PUBLISH_DO_RCS} and -f $fn) {
+		## Make the RCS directory if not there
+		my $dir;
+		$fn =~ m{(.*)/};
+		$dir = "$1/RCS";
+		File::Path::mkpath($dir) if ! -d $dir;
+
+		my $msg = errmsg("Change by %s published via PUT.", $Vend::username);
+		my @rcs_cmd = (
+					qq{ci -m"$msg" $fn >/dev/null 2>/dev/null},
+					qq{co -l $fn >/dev/null 2>/dev/null},
+					);
+
+		# See if in RCS already, check in initial if not
+		system(qq{rlog $fn >/dev/null 2>/dev/null});
+		if($?) {
+#::logDebug("RCS version was not there.");
+			my $m = $header{page_title} || 'New page';
+			$m =~ s/"/\\"/g;
+			$rcs_cmd[0] = qq{ci -i1.1 -t-"$m" $fn >/dev/null 2>/dev/null};
+			## Do nothing, there was already a version
+		}
+		else {
+#::logDebug("RCS version previously checked in.");
+			## Don't need to check in, already done
+		}
+		for(@rcs_cmd) {
+#::logDebug("RCS command: $_");
+			system $_;
+			if($?) {
+				logError("PUT RCS error on command '%s': %s", $_, $!);
+				if ($::Variable->{PUBLISH_QUIT_ON_RCS_ERROR}) {
+					$Tag->deliver('text/html', { status => "500 Server Error" }, 0);
+					umask($orig_umask) if defined $orig_umask;
+					return;
+				}
+			}
+		}
+	}
+
+#::logDebug("Getting ready to put $fn.");
+
+	my $existing = -f $fn;
+
+	unless($Tag->write_relative_file($fn, $$CGI::put_ref)) {
+		$Tag->deliver('text/html', { status => "500 Server Error" }, 0);
+		logError("PUT of $fn failed, write error.");
+		umask($orig_umask) if defined $orig_umask;
+		return;
+	}
+
+	umask($orig_umask) if defined $orig_umask;
+
+	$Vend::Session->{put_files} ||= [];
+	push (@{$Vend::Session->{put_files}}, $path);
+
+	my $status = $existing ? '204 OK' : '201 OK';
+	::logError("put of %s succeeded, status=$status.", $fn);
+
+	$Tag->deliver('text/html', { status => $status}, 1);
+	return;
+}
+EOR
 
 # user tags
 include lib/UI/vars/*







More information about the interchange-cvs mailing list