Am worked in XCart 4.4 version Framework,
Please help me How to send clean Url when send mail in Xcart.
Now in database :
Name content like :
eml_someone_ask_question_at
My Mail content value like :
I have Someone asked a question about {{product_name}} at {{STOREFRONT}}/product.php?productid={{productid}}
In my mail template page like
{$lng.eml_someone_ask_question_at|substitute:"STOREFRONT":$current_location:"productid":$productid:"product_name":$product}
Now I need to change clean url when sending before mail,
For example.
Linkpassedlike
In the above url clean url passed like,
above link need to changed like
I need to change this url when send before email please anyone help me.
1) The call chain looks like
func_send_mail->func_display('your_mail_template')->func_clean_url_filter_output->func_clean_url_product_callback->func_clean_url_get
Add an additional param like this
func_send_mail->func_display('your_mail_template',...,$new_url)->func_clean_url_filter_output(,...,$new_url)->func_clean_url_product_callback(,...,$new_url)->func_clean_url_get(,...,$new_url)
And use the $new_url URL in the func_clean_url_get instead of original one.
The function func_display may be called from the func_send_mail function
The call looks like
$mail_message = func_display($body_template,$mail_smarty,false);
2)Another solution is simply to change it in the xcart_clean_urls table.
3)Another solution
Apply the patch
diff -ru include/func/func.core.php include/func/func.core.php
--- include/func/func.core.php 2012-01-13 11:44:16.000000000 +0400
+++ include/func/func.core.php 2018-04-09 12:29:32.293262983 +0400
## -833,7 +833,7 ##
/**
* Smarty->display wrapper
*/
-function func_display($tpl, &$templater, $to_display = true, $is_intermediate = false)
+function func_display($tpl, &$templater, $to_display = true, $is_intermediate = false, $skip_output_filter = false)
{
global $config;
global $predefined_lng_variables, $override_lng_code, $shop_language, $user_agent, $__smarty_time, $__smarty_size;
## -1006,7 +1006,7 ##
$templater->register_outputfilter('func_postprocess_output');
if (func_constant('AREA_TYPE') == 'C') {
- if ($config['SEO']['clean_urls_enabled'] == 'Y')
+ if ($config['SEO']['clean_urls_enabled'] == 'Y' && !$skip_output_filter)
$templater->register_outputfilter('func_clean_url_filter_output');
if ($config['General']['use_cached_templates'] != 'Y')
diff -ru include/func/func.mail.php include/func/func.mail.php
--- include/func/func.mail.php 2012-01-10 16:27:54.000000000 +0400
+++ include/func/func.mail.php 2018-04-09 12:30:30.042523154 +0400
## -270,7 +270,8 ##
if ($config['Email']['html_mail'] != 'Y')
$mail_smarty->assign('plain_text_message', 1);
- $mail_message = func_display($body_template,$mail_smarty,false);
+ $_skip_output_filter = strpos($body_template, 'ask_question.tpl') !== false;
+ $mail_message = func_display($body_template,$mail_smarty,false, false, $_skip_output_filter);
if (X_DEF_OS_WINDOWS) {
$mail_message = preg_replace("/(?<!\r)\n/S", "\r\n", $mail_message);
And change the eml_someone_ask_question_at language variable.
Related
fn pre_dispatch(
self,
who: &Self::AccountId,
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize
) -> Result<Self::Pre, TransactionValidityError> {
let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;
Ok((self.0, who.clone(), imbalance))
}
(The above code is copied from txn-payment-pallet)
Here can we get function name and parameters from the call(one of the parameter), And based on the function-name , pallet , parameters passed by user, I want to compute fee.
For example , If it is call from pallet-staking::bond(x : amount_of_tokens_to_be_bonded) and I want to set fee for txn based on x.
Is that possible??
Like wise I want to set fee based on function-call parameters entered by user.
You can, but it requires a bit of type juggling to do so.
First, you need to realize that type Call = T::Call; in ChargeTransactionPayment. Looking at trait Config in pallet_transaction_payment, no type Call can be seen there. Instead, this type is coming from frame_system::Config (which is the super-trait of all pallets).
A brief look at the top level runtime aggregator file unravels that this Call type is essentially the outer-call of the runtime, an enum that encapsulates the call of all pallets.
That being said, the main point here is that from within pallet_transaction_payment, we cannot know of this outer-call contains this particular call from staking or not. To do so, you need to enforce this assumption via a new trait bound, namely IsSubType. This trait is specifically made to convert from wrapping type (like the outer-call) into its inner variants. See an example of this type being implemented for node_runtime's Call type.
Applying the following diff to substrate master should do exactly what you want .
diff --git a/Cargo.lock b/Cargo.lock
index ea54adf99e..df66185163 100644
--- a/Cargo.lock
+++ b/Cargo.lock
## -6074,6 +6074,7 ## dependencies = [
"frame-support",
"frame-system",
"pallet-balances",
+ "pallet-staking",
"parity-scale-codec",
"scale-info",
"serde",
diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml
index 1d3066e39f..0e705514bb 100644
--- a/frame/transaction-payment/Cargo.toml
+++ b/frame/transaction-payment/Cargo.toml
## -27,6 +27,7 ## sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primit
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
+pallet-staking = { version = "4.0.0-dev", default-features = false, path = "../staking" }
[dev-dependencies]
serde_json = "1.0.68"
## -44,5 +45,6 ## std = [
"sp-std/std",
"frame-support/std",
"frame-system/std",
+ "pallet-staking/std",
]
try-runtime = ["frame-support/try-runtime"]
diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs
index 59d94a8237..3b0803663d 100644
--- a/frame/transaction-payment/src/lib.rs
+++ b/frame/transaction-payment/src/lib.rs
## -251,7 +251,7 ## pub mod pallet {
pub struct Pallet<T>(_);
#[pallet::config]
- pub trait Config: frame_system::Config {
+ pub trait Config: frame_system::Config + pallet_staking::Config {
/// Handler for withdrawing, refunding and depositing the transaction fee.
/// Transaction fees are withdrawn before the transaction is executed.
/// After the transaction was executed the transaction weight can be
## -696,7 +696,8 ## impl<T: Config> sp_std::fmt::Debug for ChargeTransactionPayment<T> {
impl<T: Config> SignedExtension for ChargeTransactionPayment<T>
where
BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,
- T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
+ T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>
+ + frame_support::traits::IsSubType<pallet_staking::Call<T>>,
{
const IDENTIFIER: &'static str = "ChargeTransactionPayment";
type AccountId = T::AccountId;
## -736,8 +737,15 ## where
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
- let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;
- Ok((self.0, who.clone(), imbalance))
+ use frame_support::traits::IsSubType;
+ if let Some(pallet_staking::Call::bond_extra { .. }) = call.is_sub_type() {
+ // skip
+ todo!()
+ } else {
+ // default impl
+ let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;
+ Ok((self.0, who.clone(), imbalance))
+ }
}
fn post_dispatch(
Note that this approach is implying that the pallet_staking::Config be present in the runtime, which is not aligned with the modularity of Frame, and ergo is not implemented. If you want to have this feature, as of now, the only way is to fork pallet_transaction_payment and customize it a bit for your runtime.
I am making a tween that uses data given from a Humanoid.Seated event, and I wanted to make the camera go to the end point when sat down, however, move back after they sat up. I have a feeling that the problem is with the part info, however I could be wrong.
This is the code:
The Sender/Event Handler:
local camPart = script.Parent
local camEvent = game.ReplicatedStorage.CamEvent
local blueSeat = script.Parent.Parent.BlueSeat.Seat --the correct seat person should be in
local bluePlayerName = script.Parent.Parent.Buttons.BlueEnter.PlayerName --the supposed name of person
bluePlayerName:GetPropertyChangedSignal("Value"):Connect(function ()
if (bluePlayerName ~= "") then
local char = game.Workspace:FindFirstChild(bluePlayerName.Value, true)
local player = game.Players:GetPlayerFromCharacter(char)
char.Humanoid.Seated:Connect(function (isSeated, seat)
if (seat.Name == blueSeat.Name) then
camEvent:FireClient(player, camPart, isSeated) --go to tween handler
end
end)
end
end)
The Receiver/Tween Handler:
local TweenService = game:GetService("TweenService")
local cam = game.Workspace.Camera
local partData
local tween
local length = 2
local tweenData = TweenInfo.new(
length,
Enum.EasingStyle.Sine,
Enum.EasingDirection.Out,
0,
true,
0
)
script.Parent.OnClientEvent:Connect(function (camPart, isSeated) --receiver
partData = {
CFrame = camPart.CFrame
}
tween = TweenService:Create(cam, tweenData, partData)
if (isSeated == true) then
cam.CameraType = Enum.CameraType.Scriptable --remove control
tween:Play()
wait(length / 2)
tween:Pause() --stop at end point
elseif (isSeated == false) then
tween:Play() --go back/finish
wait(length / 2)
cam.CameraType = Enum.CameraType.Custom --give control back
end
end)
The fact that the RemoteEvent isn't firing at all should be an clue that the connection to the Humanoid.Seated event isn't being reached in the server Script. It's unclear from your code sample what would trigger the code in the first place, but it looks like you're just looking for when a player's character loads into the workspace.
I would recommend using the Player.CharacterAdded or Player.CharacterAppearanceLoaded events as ways of getting access to the player's Character and humanoid. You can still use your UI code as a trigger for whether to tween or not, but it might be easier.
-- Server Script
local camPart = script.Parent
local camEvent = game.ReplicatedStorage.CamEvent
local thing = script.Parent.Parent
local blueSeat = thing.BlueSeat.Seat --the correct seat person should be in
local bluePlayerName = thing.Buttons.BlueEnter.PlayerName --the supposed name of person
-- listen for when a player sits in a seat
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
character.Humanoid.Seated:Connect(function(isSeated, seat)
print("Player is seated?", isSeated)
if not isSeated then
-- tell the client to zoom out
camEvent:FireClient(player, camPart, isSeated)
else
-- decide whether to tween the camera
local isApprovedSeat = seat.Name == blueSeat.Name
local isNameSet = bluePlayerName.Value ~= ""
local shouldTweenCamera = isApprovedSeat and isNameSet
if shouldTweenCamera then
camEvent:FireClient(player, camPart, isSeated)
else
local message = table.concat({
"Camera not tweening because: ",
"Player has claimed this seat? " .. tostring(hasClaimedSeat),
"This is the approved seat? " .. tostring(isApprovedSeat)
}, "\n")
warn(messsage)
end
end
end)
end)
end)
Also, it looks like the LocalScript that is listening for this RemoteEvent is located in ReplicatedStorage. Check the documentation on LocalScripts, they only fire in a handful of locations, and ReplicatedStorage unfortunately isn't one of them. Try moving the LocalScript into StarterCharacterScripts and update the path to the RemoteEvent.
local camEvent = game.ReplicatedStorage.CamEvent
camEvent.OnClientEvent:Connect(function (camPart, isSeated) --receiver
I suppose I'm missing something obvious here, but I've been stumped for a while on this. I have my .Rmd file setup, and almost everything knits fine to Markdown_strict and latex_fragment (with a little preprocessing on that one), but nevermind for now.
Here's a sample.Rmd file that I have as input. I couldn't figure how to nest backticks, so for now it's pseudo-escaped.
---
title: "Sample"
output:
md_document:
preserve_yaml: yes
variant: markdown_strict+raw_html+all_symbols_escapable
latex_fragment: default
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile, encoding = encoding,
output_dir = ".", output_format = "all") })
---
\`\`\`{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
sqlcode <- function(sql, code = "") {
if (knitr::is_latex_output()) {
return(paste0('\n```{=sql}\n',sql,'\n```\n'))
} else if (!knitr::is_html_output(excludes = "markdown")) {
if (length(code)>0) {
code = paste0(" ", code," ")
} else {
code = " "
}
pre <- paste0("{{< sql",code,">}}\n")
post <- "\n{{< /sql >}}"
return(knitr::raw_html(paste0(pre,sql,post)))
}
}
\`\`\`
This is a sample.
\`\`\`{r echo=FALSE}
sqlcode("SELECT *
FROM TABLE", "sample")
\`\`\`
The LaTeX fragment I want is:
This is a sample.
\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{SELECT} \OperatorTok{*}
\KeywordTok{FROM}\NormalTok{ TABLE}
\end{Highlighting}
\end{Shaded}
What I get is:
This is a sample.
\begin{verbatim}
## [1] "\n```{=sql}\nSELECT *\nFROM TABLE\n```\n"
\end{verbatim}
And on the MD side, I do get what I want, that is:
---
title: "Sample"
output:
md_document:
preserve_yaml: yes
variant: markdown_strict+raw_html+all_symbols_escapable
latex_fragment: default
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile, encoding = encoding,
output_dir = ".", output_format = "all") })
---
This is a sample.
{{< sql sample >}}
SELECT *
FROM TABLE
{{< /sql >}}
For those familiar with Hugo, these are custom shortcodes I use for a Hugo-generated site. The lack of ident of the SQL code is on purpose, it's then highlighted through hugo.
At any rate, how do I get sqlcode(...) to output a fenced block that pandoc will correctly highlight in LaTeX, or alternatively, what part of pdf_document.R should I customize in order to achieve that ?
I've tried various knitr functions that mark output and I can get an intermediary MD file that I could process to remove some markers, but I can't manage to process that intermediary MD file before knitr sends it to Pandoc.
After a while of trial and error I figured it out. It's as simple as changing one line -_-
sqlcode <- function(sql, code = "") {
if (knitr::is_latex_output()) {
knitr::raw_output(paste0('\n```sql\n',sql,'\n```\n'), markers=NULL)
} else if (!knitr::is_html_output(excludes = "markdown")) {
if (length(code)>0) {
code = paste0(" ", code," ")
} else {
code = " "
}
pre <- paste0("{{< sql",code,">}}\n")
post <- "\n{{< /sql >}}"
return(knitr::raw_html(paste0(pre,sql,post)))
}
}
I'm trying to use jenkinsPipelineUnit to test a JenkinsFile that exists in the same git repository as my shared libraries. This Jenkinsfile references shared libraries located in src. It appears that I must commit my shared library changes before I can test them even if I use localSource from within the retriever.
How can I load my shared libraries and unit test them without committing the code first?
Here is my current code that doesn't work:
def library = library().name('pipeline-utils')
.defaultVersion("master")
.allowOverride(true)
.implicit(false)
.targetPath(sharedLibs)
.retriever(localSource(sharedLibs))
.build()
helper.registerSharedLibrary(library)
try {
def script = runScript("pipelines/test.groovy")
}
I get this error:
file:/Users/<myuserid>/git/pipelines/test.groovy: 2:
Error on loading library pipeline-utils#myteam/pipelineUnitTest :
Directory /Users/<myuserid>/git/out/test/classes/com/company/test/pipeline-utils#myteam/pipelineUnitTest does not exists # line 2, column 1.
#Library("pipeline-utils#myteam/pipelineUnitTest") _
This isn't as easy as it sounds. JenkinsPipelineUnit isn't moving any more since one year while some interesting work is waiting on pull-requests. Here are the steps I had to go through to get this working locally, but also on jenkins where the name of my repository directory can be different each time.
1. Create a custom version of JenkinsPipelineUnit
I started from https://github.com/jenkinsci/JenkinsPipelineUnit/pull/75 but had to add some other changes. These are all the changes:
diff --git a/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryConfiguration.groovy b/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryConfiguration.groovy
index f4eeb17..dc13b9c 100644
--- a/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryConfiguration.groovy
+++ b/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryConfiguration.groovy
## -18,7 +18,7 ## class LibraryConfiguration {
String targetPath
LibraryConfiguration validate() {
- if (name && defaultVersion && retriever && targetPath)
+ if (name && retriever && targetPath && ((retriever instanceof LocalSource || defaultVersion)))
return this
throw new IllegalStateException("LibraryConfiguration is not properly initialized ${this.toString()}")
}
diff --git a/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryLoader.groovy b/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryLoader.groovy
index 120a316..a253f2d 100644
--- a/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryLoader.groovy
+++ b/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryLoader.groovy
## -117,11 +117,14 ## class LibraryLoader {
}
private static boolean matches(String libName, String version, LibraryConfiguration libraryDescription) {
+ if (libraryDescription.allowOverride) {
+ return true
+ }
if (libraryDescription.name == libName) {
if (version == null) {
return true
}
- if (libraryDescription.allowOverride || libraryDescription.defaultVersion == version) {
+ if (libraryDescription.defaultVersion == version) {
return true
}
}
diff --git a/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LocalSource.groovy b/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LocalSource.groovy
index 61babde..4edca23 100644
--- a/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LocalSource.groovy
+++ b/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LocalSource.groovy
## -11,7 +11,13 ## class LocalSource implements SourceRetriever {
#Override
List<URL> retrieve(String repository, String branch, String targetPath) {
- def sourceDir = new File(sourceURL).toPath().resolve("$repository#$branch").toFile()
+ def sourceURLPath = new File(sourceURL).toPath()
+ def sourceDir
+ if (branch) {
+ sourceDir = sourceURLPath.resolve("$repository#$branch").toFile()
+ } else {
+ sourceDir = sourceURLPath.resolve(repository).toFile()
+ }
if (sourceDir.exists()) {
return [sourceDir.toURI().toURL()]
}
2. Register your current repository directory as your shared library
Inspired from: https://github.com/jimcroft/jenkinslib-example/blob/master/test/com/example/TestCase1.groovy
in your TestClass.groovy:
void setup() {
String repositoryDirectoryName = FilenameUtils.getName(System.getProperty("user.dir"))
String dirPath = new File( System.getProperty("user.dir") )
.getAbsoluteFile()
.getParentFile()
.getAbsolutePath()
// This next call bypasses registerSharedLibrary; to allow registering a library with a different directory name
helper.libraries.put('my-jenkins-library', library(repositoryDirectoryName)
.allowOverride(true)
.implicit(false)
.targetPath(dirPath)
.retriever(localSource(dirPath))
.build())
I try to implement "streaming contents" on my Pythonanywhere account.
It looks more or less to what is shown there:
cf. http://flask.pocoo.org/docs/0.10/patterns/streaming/
except that my view is calculating a complex process for maybe one minute and yields its data to my template, where a script is supposed to update some progress bars (''source.onmessage'').
This works perfectly on my development machine, but not on my pythonanywhere account. On this server, the process looks jammed (progress bars are never updated, except at the very end where the suddunly grow from 0% to 100%), although everything goes well under the hood, e.g. my print statements are correctly rendered into my server logs).
In the snippet quoted above, there is a note:
Note though that some WSGI middlewares might break streaming, so be
careful there in debug environments with profilers and other things
you might have enabled.
Could it be the problem here? and would there be a workaround?
JS code from my jinja2 template:
<script type="text/javascript">
/* progress bar */
var source = new EventSource("{{ url_for('BP.run', mylongprocess_id=mylongprocess_id) }}");
source.onmessage = function(event) {
console.log(event.data);
var data = event.data.split("!!");
var nodeid = data[0];
var process = data[1];
var process_status = data[2];
var postpro = data[3];
var postpro_status = data[4];
$('.pb1').css('width', process+'%').attr('aria-valuenow', process);
$('.pb2').css('width', postpro+'%').attr('aria-valuenow', process);
document.getElementById("process_status").innerHTML = process_status;
document.getElementById("postpro_status").innerHTML = postpro_status;
document.getElementById("nodeid").innerHTML = nodeid;
if (postpro >= 100) {
setTimeout(function() {
console.log("progress is finished!");
document.getElementById("status").innerHTML = "redirecting to {{url_for('.view_sonix_result', mylongprocess_id=mylongprocess_id)}}";
window.location.replace("{{url_for('.terminate_analysis', mylongprocess_id=mylongprocess_id)}}");
}, 2); // / setTimeout function
} // /if
else {
document.getElementById("status").innerHTML = "pending...";
} // /else
} // /function
</script>
My (simplified) view:
#BP.route('/run/<int:mylongprocess_id>')
#login_required
def run(mylongprocess_id):
mylongprocess = mylongprocess.query.get_or_404(mylongprocess_id)
project = Project.query.get_or_404(mylongprocess.project_id)
check_rights(current_user, project, 'user', 404)
A, lcs = _create_analysis(mylongprocess)
#copy_current_request_context
def gen(mylongprocess, nodeid, store_path):
print('now runing %s' % A)
for (loopnb, total_loops, pct, lclabel) in A.runiterator(lcs):
print('ran %d/%d (%.1f%%) "%s"' % (loopnb, total_loops,
pct, lclabel))
progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
(nodeid, pct, lclabel, 0, 'waiting...'))
yield progress
print('now postprocessing %s' % A)
postpro = load_node(store_path, node_id=nodeid)
for step, total, pct, action in postpro._builditer(target='web',
buildfile=None):
progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
(nodeid, 100, 'ok', pct, action.replace('_', ' ')))
yield progress
print('now terminating %s' % A)
_terminate_analysis(A, mylongprocess)
return Response(gen(mylongprocess, mylongprocess.nodeid), mimetype='text/event-stream')
Your traffic goes through an nginx proxy when it is hosted on PythonAnywhere and nginx buffers the response unless specified otherwise.
To get everything to flush,
give your flask responses headers response.headers['X-Accel-Buffering'] = 'no'
have a '\n' at the end of the string you are yielding because python also buffers till end of line.